Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions autolens/analysis/latent.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,12 +387,17 @@ def total_source_flux_mujy(fit, magzero, xp=np):
)


def magnification(fit, magzero, xp=np):
def magnification(fit, magzero=None, xp=np):
"""
Ratio of image-plane to source-plane source flux — the integrated
magnification implied by the lens model and the source's light.

The denominator is :func:`total_source_flux_mujy`: light-profile flux
Computed from the raw-flux latents :func:`total_lensed_source_flux` and
:func:`total_source_flux`, so it needs no ``magzero`` (the ratio is
dimensionless; a µJy conversion would only multiply both fluxes by the
same factor).

The denominator is :func:`total_source_flux`: light-profile flux
plus, for a pixelized source, the inversion's reconstruction integrated
with its ``areas_for_magnification`` (barycentric dual areas for a
Delaunay mesh — PyAutoArray#524 — transformed cell areas for a rectangular
Expand All @@ -402,12 +407,11 @@ def magnification(fit, magzero, xp=np):
scale. A source whose only light model is a ``Pixelization`` therefore has
a finite magnification rather than an infinite one (PyAutoLens#726).

``magzero`` is accepted but unused (the µJy conversions cancel in the
ratio). It's still required in the signature so the dispatcher can
pass a uniform context dict to every latent function.
``magzero`` is accepted but unused, so the dispatcher can pass a uniform
context dict to every latent function.
"""
lensed = total_lensed_source_flux_mujy(fit=fit, magzero=magzero, xp=xp)
intrinsic = total_source_flux_mujy(fit=fit, magzero=magzero, xp=xp)
lensed = total_lensed_source_flux(fit=fit, xp=xp)
intrinsic = total_source_flux(fit=fit, xp=xp)
return lensed / intrinsic


Expand Down
12 changes: 6 additions & 6 deletions autolens/config/latent.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ total_lensed_source_flux_mujy: false
total_source_flux_mujy: false

# `magnification` — ratio of image-plane lensed source flux to source-plane
# intrinsic source flux. Dimensionless; `magzero` is accepted but unused.
# Default `false` because it routes through the `_mujy` latents internally
# (the µJy conversions cancel in the ratio) — to flip on, also flip on
# `total_lensed_source_flux_mujy` and `total_source_flux_mujy` and supply
# a `magzero`. A follow-up could rewire `magnification` to the raw-flux
# latents so it's universally enable-able.
# intrinsic source flux, from the raw-flux latents above. Dimensionless and
# needs no `magzero`. Works for light-profile and pixelized sources. Default
# `false` (opt-in): set it `true` to get its posterior from the fit's samples.
# Magnifications at individual image positions are not latents, because the
# number of images differs between lenses; compute them from posterior draws
# as the `source_science.py` examples do.
magnification: false

# `effective_einstein_radius` — effective Einstein radius in arcseconds,
Expand Down
31 changes: 30 additions & 1 deletion test_autolens/analysis/test_latent.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,6 @@ def test_maybe_magzero_warn_logs_only_once_per_name(caplog):

def test_magnification_is_lensed_over_intrinsic():
# Image-plane lensed source flux = 10, source-plane intrinsic = 2.
# The µJy conversions cancel in the ratio, so the result is 5.0.

class _FakeSourceGalaxy:
# Plain class so instances are hashable (used as galaxy_image_dict key).
Expand Down Expand Up @@ -974,3 +973,33 @@ def test_latent_lens_variables_traces_under_jit_with_model_assertion(
assert np.allclose(
[float(v) for v in values], [float(v) for v in values_np], rtol=1e-6
)


def test_magnification_needs_no_magzero():
"""The magnification latent is the raw-flux ratio, so it is finite without a
``magzero`` and equal to the ratio of the raw-flux latents."""
from autolens.analysis.latent import (
total_lensed_source_flux,
total_source_flux,
)

class _FakeSourceGalaxy:
def image_2d_from(self, grid, xp=np):
return SimpleNamespace(array=np.array([2.0]))

source = _FakeSourceGalaxy()
galaxies_namespace = SimpleNamespace(galaxies=[object(), source])
fit = SimpleNamespace(
tracer=galaxies_namespace,
tracer_linear_light_profiles_to_light_profiles=galaxies_namespace,
galaxy_image_dict={source: SimpleNamespace(array=np.array([10.0]))},
dataset=SimpleNamespace(grids=SimpleNamespace(lp=object())),
)

value = magnification(fit=fit, magzero=None)

assert np.isfinite(value)
assert value == pytest.approx(
total_lensed_source_flux(fit=fit) / total_source_flux(fit=fit)
)
assert magnification(fit=fit, magzero=25.0) == pytest.approx(value)
Loading