Skip to content

Commit 1044d4e

Browse files
Jammy2211claude
authored andcommitted
Add visibility-space potential corrections (interferometer phase 1)
Adds al.pc.FitDpsiSrcInterferometer — the joint source+dpsi inversion of interferometer visibilities — with the sparse-operator (w-tilde) route as the primary implementation (joint curvature via the dataset's InterferometerSparseOperator FFT machinery from extent-indexed COO triplets; data vector via the dirty image; chi2 via one forward NUFFT; scales with real-space pixels, independent of visibility count) and the dense transform_mapping_matrix route as the small-n_vis parity reference. Adds DpsiSrcInvInterferometerAnalysis + docs entries. Sparse route verified identical to the dense route on the interferometer_7 fixture. Phase 1 of #623 (parent epic #618). Ported and extended from Cao et al. 2025 (https://github.com/caoxiaoyue/lensing_potential_correction); cite via https://github.com/caoxiaoyue/potential_correction_paper. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 3983f49 commit 1044d4e

5 files changed

Lines changed: 679 additions & 0 deletions

File tree

autolens/potential_correction/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
from autolens.potential_correction.src_factory import PixSrcFactoryITP
2525
from autolens.potential_correction.fit import FitDpsiImaging
2626
from autolens.potential_correction.fit import FitDpsiSrcImaging
27+
from autolens.potential_correction.fit_interferometer import FitDpsiSrcInterferometer
2728
from autolens.potential_correction.analysis import DpsiInvAnalysis
2829
from autolens.potential_correction.analysis import DpsiSrcInvAnalysis
30+
from autolens.potential_correction.analysis import DpsiSrcInvInterferometerAnalysis
2931
from autolens.potential_correction import dense_util
3032
from autolens.potential_correction.iterative import IterFitDpsiSrcImaging
3133
from autolens.potential_correction.iterative import IterDpsiSrcInvAnalysis

autolens/potential_correction/analysis.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,84 @@ def log_likelihood_function(self, instance):
7676
return fit.log_evidence
7777

7878

79+
class DpsiSrcInvInterferometerAnalysis(af.Analysis):
80+
def __init__(
81+
self,
82+
dataset,
83+
lens_start: Galaxy,
84+
source_start: SrcFactory,
85+
src_image_mesh=None,
86+
settings_inversion: Optional[aa.Settings] = None,
87+
use_sparse_operator: bool = True,
88+
preloads: Optional[dict] = None,
89+
):
90+
"""
91+
Samples the joint source+dpsi pixelization of a visibility-space
92+
joint inversion (``FitDpsiSrcInterferometer``), with the inversion's
93+
Bayesian evidence as the likelihood.
94+
95+
Parameters
96+
----------
97+
dataset
98+
The ``al.Interferometer`` dataset; for the sparse-operator route
99+
(default) call ``dataset.apply_sparse_operator()`` first.
100+
lens_start
101+
The smooth lens galaxy of the starting model.
102+
source_start
103+
The source factory evaluated for the source gradients.
104+
src_image_mesh
105+
An image mesh whose image-plane mesh grid is preloaded into the
106+
source inversion.
107+
settings_inversion
108+
The inversion settings; defaults to the positive-only solver
109+
with the border relocator.
110+
use_sparse_operator
111+
Whether fits run through the sparse w-tilde operator (default)
112+
or the dense transformed mapping matrix.
113+
preloads
114+
Precomputed fit attributes shared across evaluations.
115+
"""
116+
self.dataset = dataset
117+
self.lens_start = lens_start
118+
self.source_start = source_start
119+
self.src_image_mesh = src_image_mesh
120+
if settings_inversion is None:
121+
self.settings_inversion = aa.Settings(
122+
use_positive_only_solver=True,
123+
use_border_relocator=True,
124+
)
125+
else:
126+
self.settings_inversion = settings_inversion
127+
self.use_sparse_operator = use_sparse_operator
128+
self.preloads = preloads
129+
130+
def log_likelihood_function(self, instance: DpsiSrcPixelization):
131+
from autolens.potential_correction.fit_interferometer import (
132+
FitDpsiSrcInterferometer,
133+
)
134+
135+
fit = FitDpsiSrcInterferometer(
136+
dataset=self.dataset,
137+
lens_start=self.lens_start,
138+
source_start=self.source_start,
139+
dpsi_pixelization=instance.dpsi_pixelization,
140+
src_pixelization=instance.src_pixelization,
141+
src_image_mesh=self.src_image_mesh,
142+
settings_inversion=self.settings_inversion,
143+
use_sparse_operator=self.use_sparse_operator,
144+
preloads=self.preloads,
145+
)
146+
try:
147+
return fit.log_evidence
148+
except exc.InversionException:
149+
# a failed inversion is a valid (very bad) sample, not a crash
150+
logger.exception(
151+
"InversionException during visibility-space joint source+dpsi "
152+
"evidence evaluation; returning penalty likelihood."
153+
)
154+
return -1e8
155+
156+
79157
class DpsiSrcInvAnalysis(af.Analysis):
80158
def __init__(
81159
self,

0 commit comments

Comments
 (0)