Repository navigation
feat: al.twins model builder and posterior recovery table (LensTwin 4a) - #811
Merged
Merged
Conversation
Add al.twins.model.stellar_dark_model_from, which builds the no-misspecification inference model of a ReplaceTotalMassWithStellarPlusDark twin (fixed MGE light as lmp.Gaussian with one shared mass_to_light_ratio, dark halo centred on the light, free shear as a galaxy attribute or MassField field, broad fixed priors), and al.twins.recovery.recovery_table_from, which compares posterior medians and sigma bounds with the twin's truth. truth_paths_from is the single truth-key -> model-path map both use. Closes #810 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ReplaceTotalMassWithStellarPlusDark only recognised bare ExternalShear tracer fields; DR1-style tracers hold a MassField with a .shear component, so keep_shear=False neither removed nor recorded it. Shear components inside a MassField are now found by attribute, removed from the copy (the field is dropped when no mass component remains) and recorded as fields.<i>.<key>. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Jammy2211
marked this pull request as ready for review
October 29, 2026 21:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #810
What it adds
al.twins.stellar_dark_model_from(twin, galaxy=None, *, source_model, free_scale_radius=True, free_inner_slope=None, free_shear=True, priors=None) -> af.CollectionThis builds the model that fits a stellar-plus-dark twin with the same parameterization it was made with, so the model is not misspecified. It is the twin-based version of
ag.analysis.chaining_util.mass_light_dark_basis_from. It reads the lastReplaceTotalMassWithStellarPlusDarkrecord (requested["light"],requested["dark_name"]andtruth) and the twin's tracer. If the twin has no such record, it raisesValueError.The lens light basis becomes a
Basisofaf.Model(lmp.Gaussian). Each member's centre, ell_comps, sigma and intensity are fixed to the twin's values, and all members share onemass_to_light_ratioprior object.The dark profile is
af.Model(<the twin's dark class>), with its centre fixed totruth["dark_centre"].kappa_sis free.scale_radiusis free, or fixed to the truth whenfree_scale_radius=False.inner_slopeis free only for classes that take it as a constructor argument (e.g.gNFWSph, notNFWSph).Shear: an
ExternalSheargalaxy attribute becomesaf.Model(ExternalShear). A tracerMassFieldis mirrored asfields=af.Model(al.MassField, redshift=<field z>, shear=af.Model(al.mp.ExternalShear)), which is the workspace and DR1 layout. Several fields giveaf.Collection(field_0=..., ...). Withfree_shear=Falsethe shear is fixed to the twin's values.source_modelreplaces the galaxy named"source"(otherwise the single highest-redshift galaxy). It can also be a{name: model}dict. All other galaxies stay as fixed instances under their names.Default priors are broad, fixed and never derived from the truth (
DEFAULT_PRIORS):You can override any of them with
priors={truth_key: prior}.al.twins.truth_paths_from(model, galaxy)maps each truth key (mass_to_light_ratio,kappa_s,scale_radius_arcsec,inner_slope) to the path of its free model parameter. The model builder and the recovery table both use this one map.al.twins.recovery_table_from(samples, truth, paths=None, sigma=3.0) -> RecoveryTablename, path, truth, median, lower, upper, inside. The table hasall_inside,to_csv, a readable__str__andtable["kappa_s"]lookup.truthcan be a dict, atwin.jsonpath or the directory that holds it. From the file it uses the last stellar-dark entry of the"truth"block.median_pdf(as_instance=False)and bounds fromvalues_at_sigma(sigma, as_instance=False). Columns are looked up throughsamples.paths, which groups the paths of tied priors, so the path of any member of the shared M/L finds its column.SamplesSummaryis accepted for sigma 1 or 3.Tests
test_autolens/twins/test_model.py(10 tests):MassFieldfield, checked throughAnalysisImaging.tracer_via_instance_fromtest_autolens/twins/test_recovery.py(5 tests):SamplesPDFwith the truth inside and outside the boundstwin.jsonand from a directorySamplesSummaryPYAUTO_TEST_MODE=1: simulate, build the model, run real Nautilus on a reduced budget, write the table. It takes about 25 s with figure saving patched out (about 115 s otherwise).pytest test_autolens/twins -n 4: 54 passed🤖 Generated with Claude Code