From d6090b72fe1b0255a6a02d83d20ebe95334f719e Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Thu, 9 Jul 2026 11:21:16 +0100 Subject: [PATCH] Demo shear profile + convergence map; adopt should_simulate in weak scripts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - scripts/weak/fit.py: __Shear Profile__ section — binned gamma_t data-vs-model overlay with the gamma_x B-mode null test via the new aplt.plot_shear_profile; adopts the standard __Dataset Auto-Simulation__ pattern (al.util.dataset.should_simulate) per user direction - scripts/weak/simulator.py: __Convergence Map__ section — Kaiser-Squires E-mode reconstruction via the new aplt.plot_convergence_map - scripts/weak/modeling.py: migrate plain exists() check to should_simulate - navigator catalogue regenerated (Contents lines changed) Step 6 of the weak-lensing series (PyAutoLabs/PyAutoLens#581). Co-Authored-By: Claude Fable 5 --- llms-full.txt | 2 +- scripts/weak/fit.py | 37 ++++++++++++++++++++++++++++++++++++- scripts/weak/modeling.py | 2 +- scripts/weak/simulator.py | 22 ++++++++++++++++++++++ workspace_index.json | 5 ++++- 5 files changed, 64 insertions(+), 4 deletions(-) diff --git a/llms-full.txt b/llms-full.txt index 1d6fc642d..b46563695 100644 --- a/llms-full.txt +++ b/llms-full.txt @@ -431,7 +431,7 @@ AUTO-GENERATED by PyAutoBuild — do not edit by hand; regenerate with generate. ## weak - [Fit: Weak Lensing](scripts/weak/fit.py): This script shows how to fit a strong-lens mass model to a weak gravitational lensing shear catalogue. Where the `imaging` and `interferometer` workflows fit a 2D image of a lensed source, the weak-lensing workflow fits a set of (gamma_2, gamma_1) shear measurements at the (y, x) positions of background source galaxies — a ``WeakDataset`` produced by the simulator script in `scripts/weak/simulator.py`. - - Contents: Dataset, Model, Fit, Visualization, Notes + - Contents: Dataset, Model, Fit, Visualization, Shear Profile, Notes - [Modeling: Weak Lensing](scripts/weak/modeling.py): This script fits a lens mass model to a weak gravitational lensing shear catalogue using a non-linear search. It is the weak-lensing analogue of `scripts/imaging/modeling.py`: where that script infers a lens model from a 2D image of a lensed source, this script infers one from the (gamma_2, gamma_1) shear measurements of background source galaxies — a `WeakDataset` produced by `scripts/weak/simulator.py`. - Contents: Dataset, Model, Search, Analysis, Run Times, Model-Fit, Output Folder Layout, Result - [Simulator: Weak Lensing](scripts/weak/simulator.py): This script simulates a weak gravitational lensing shear catalogue. Unlike the imaging simulator (which produces a 2D image of the lensed source) the weak-lensing simulator produces a *catalogue* of (gamma_2, gamma_1) shear measurements at the (y, x) positions of a population of background source galaxies. diff --git a/scripts/weak/fit.py b/scripts/weak/fit.py index 2c7a2338f..8d97e9580 100644 --- a/scripts/weak/fit.py +++ b/scripts/weak/fit.py @@ -18,6 +18,7 @@ - **Model:** Build a lens-model `Tracer` whose mass profiles produce the model shear field. - **Fit:** Construct a `FitWeak` and inspect its derived quantities (residuals, chi-squared, log-likelihood). - **Visualization:** Plot the fit as a 2x2 mosaic of data, model, overlay, and chi-squared map. +- **Shear Profile:** Bin the tangential/cross shear about the lens centre and compare data to model. - **Notes:** What a "good" fit looks like and how this script relates to the upcoming modeling tutorial. """ @@ -38,10 +39,22 @@ vector and per-galaxy noise standard deviation 0.3. The shear field carries the signature of the foreground lens's mass distribution. -If `dataset.json` does not yet exist, run `scripts/weak/simulator.py` first. +__Dataset Auto-Simulation__ + +If the dataset does not already exist on your system, it will be created by running the corresponding +simulator script. This ensures that all example scripts can be run without manually simulating data first. """ dataset_path = Path("dataset") / "weak" / "simple" +if al.util.dataset.should_simulate(str(dataset_path)): + import subprocess + import sys + + subprocess.run( + [sys.executable, "scripts/weak/simulator.py"], + check=True, + ) + dataset = al.from_json(file_path=dataset_path / "dataset.json") print(dataset.info) @@ -123,6 +136,28 @@ output_format="png", ) +""" +__Shear Profile__ + +The panels above show the fit galaxy by galaxy; cluster weak-lensing results are usually shown instead as +the azimuthally averaged *tangential shear profile* `gamma_t(r)` — the mean tangential stretching of +background galaxies in radial bins about the lens centre, which traces the projected mass profile (this is +the standard observable of analyses such as the Sloan Giant Arcs Survey and the Frontier Fields clusters). + +`aplt.plot_shear_profile` bins the catalogue about a chosen centre and, because we pass it the `FitWeak`, +overlays the model shear's tangential profile as a line. The plot also shows the *cross* component +`gamma_x` (the 45-degree rotated component): gravitational lensing produces none at leading order, so the +cross points scattering around zero is the standard "B-mode" null test — a systematic contaminating the +measurement would show up here. +""" +aplt.plot_shear_profile( + fit, + centre=(0.0, 0.0), + bins=8, + output_path=dataset_path, + output_format="png", +) + """ __Notes__ diff --git a/scripts/weak/modeling.py b/scripts/weak/modeling.py index 20ff409a2..102507001 100644 --- a/scripts/weak/modeling.py +++ b/scripts/weak/modeling.py @@ -69,7 +69,7 @@ dataset_name = "simple" dataset_path = Path("dataset") / "weak" / dataset_name -if not (dataset_path / "dataset.json").exists(): +if al.util.dataset.should_simulate(str(dataset_path)): import subprocess import sys diff --git a/scripts/weak/simulator.py b/scripts/weak/simulator.py index 0ba210ec6..0762522f1 100644 --- a/scripts/weak/simulator.py +++ b/scripts/weak/simulator.py @@ -121,5 +121,27 @@ output_format="png", ) +""" +__Convergence Map__ + +The shear field can be inverted directly into a map of the convergence `kappa` (the dimensionless projected +mass density) using the Kaiser-Squires (1993) technique: in Fourier space shear and convergence are related +algebraically, so two FFTs turn the catalogue into a "dark matter map" with no mass model assumed. This is +the classic visualization used for merging clusters (e.g. the Bullet cluster) and survey mass maps. + +`aplt.plot_convergence_map` bins the irregular catalogue onto a regular grid, applies a small Gaussian +smoothing (raw per-cell shears are shape-noise dominated) and plots the E-mode reconstruction. For this +Isothermal lens the map peaks at the lens centre at (0.0", 0.0"). Two caveats to remember: the mean of the +map is unconstrained (the mass-sheet degeneracy) and FFT periodicity causes artefacts near the field edges — +for quantitative masses, fit a mass model with `scripts/weak/modeling.py` instead. +""" +aplt.plot_convergence_map( + shear_yx=dataset.shear_yx, + shape_native=(30, 30), + smoothing_sigma_pixels=1.0, + output_path=dataset_path, + output_format="png", +) + print(dataset.info) print(f"Wrote dataset to {dataset_path}") diff --git a/workspace_index.json b/workspace_index.json index e46633dd9..ce53e45af 100644 --- a/workspace_index.json +++ b/workspace_index.json @@ -5791,6 +5791,7 @@ "Model", "Fit", "Visualization", + "Shear Profile", "Notes" ], "cross_refs": [ @@ -5836,7 +5837,9 @@ "Output", "Visualize" ], - "cross_refs": [], + "cross_refs": [ + "scripts/weak/modeling.py" + ], "notebook": "notebooks/weak/simulator.ipynb", "path": "scripts/weak/simulator.py", "summary": "This script simulates a weak gravitational lensing shear catalogue. Unlike the imaging simulator (which produces a 2D image of the lensed source) the weak-lensing simulator produces a *catalogue* of (gamma_2, gamma_1) shear measurements at the (y, x) positions of a population of background source galaxies.",