Skip to content

fix: total_source_flux_mujy wrong value for linear light profiles #535

@Jammy2211

Description

@Jammy2211

Bug

autolens/analysis/latent.py::total_source_flux_mujy (shipped in #534) returns wrong values for fits using linear light profiles (any lp_linear.* or MGE basis).

def total_source_flux_mujy(fit, magzero, xp=np):
    ...
    source_image = fit.tracer.galaxies[-1].image_2d_from(
        grid=fit.dataset.grids.lp, xp=xp
    )

For linear light profiles, fit.tracer.galaxies[-1] has unsolved profiles (the inversion fills intensities at fit time, but fit.tracer doesn't apply them). image_2d_from returns zeros / garbage.

Transitively breaks magnification too (numerator uses galaxy_image_dict which IS correct for linear; denominator is the broken image_2d_from).

The euclid pipeline already has the workaround locally — see euclid_strong_lens_modeling_pipeline/util.py:378:

tracer = fit.tracer_linear_light_profiles_to_light_profiles

This PR lifts that fix into the library so other lens projects using linear profiles get correct values without each one re-discovering the issue.

Fix

Read from fit.tracer_linear_light_profiles_to_light_profiles (which returns the tracer with linear-profile intensities filled in from the inversion's linear_light_profile_intensity_dict):

def total_source_flux_mujy(fit, magzero, xp=np):
    ...
    # tracer_linear_light_profiles_to_light_profiles returns the tracer
    # with linear-profile intensities filled in from the inversion.
    # For non-linear fits it's a no-op pass-through (returns fit.tracer).
    tracer = fit.tracer_linear_light_profiles_to_light_profiles
    source_image = tracer.galaxies[-1].image_2d_from(
        grid=fit.dataset.grids.lp, xp=xp
    )

Stress-test:

  • Non-linear fits: autogalaxy/abstract_fit.py:214 early-returns self.model_obj when no linear profiles are present — pure no-op pass-through, existing tests still pass.
  • Linear-profile fits: append_linear_light_profiles_to_model(...) rebuilds the tracer with intensities from the inversion (already cached as a side-effect of figure_of_merit).
  • JIT path: euclid uses this exact pattern under LATENT_BATCH_MODE = "jit" in production.
  • magnification inherits the fix transitively.

total_lens_flux_mujy, total_lensed_source_flux_mujy, and effective_einstein_radius are unchanged — they're already correct.

Test Plan

  • Add test_total_source_flux_mujy_uses_converted_tracer_for_linear_profiles — build a fit fixture where fit.tracer.galaxies[-1].image_2d_from() returns zeros (unsolved) and fit.tracer_linear_light_profiles_to_light_profiles.galaxies[-1].image_2d_from() returns the expected non-zero image; assert the function reads from the solved tracer.
  • Update existing test_total_source_flux_mujy_against_known_image and test_magnification_is_lensed_over_intrinsic fixtures to expose the new attribute.
  • pytest test_autolens/ — full suite (~311 tests) green.

Context

Discovered while reading euclid_strong_lens_modeling_pipeline/util.py:378 during the planning of #17 (Euclid pipeline migration). The euclid migration is paused waiting for this fix to land — once merged, the euclid pipeline can inherit the corrected library and drop its own tracer_linear_light_profiles_to_light_profiles line.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions