Skip to content

Commit ca5023c

Browse files
Jammy2211Jammy2211
authored andcommitted
update to positions_likelihood_list
1 parent 0d878df commit ca5023c

4 files changed

Lines changed: 81 additions & 103 deletions

File tree

autolens/analysis/analysis/dataset.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import os
22
import logging
3-
from typing import Optional, Union
3+
from typing import List, Optional, Union
44

55
from autoconf import conf
6-
from autoconf.dictable import to_dict, output_to_json
6+
from autoconf.dictable import output_to_json
77

88
import autofit as af
99
import autoarray as aa
@@ -27,8 +27,8 @@ class AnalysisDataset(AgAnalysisDataset, AnalysisLens):
2727
def __init__(
2828
self,
2929
dataset,
30-
positions_likelihood: Optional[
31-
Union[PositionsLHResample, PositionsLHPenalty]
30+
positions_likelihood_list: Optional[
31+
List[Union[PositionsLHResample, PositionsLHPenalty]]
3232
] = None,
3333
adapt_image_maker: Optional[ag.AdaptImageMaker] = None,
3434
cosmology: ag.cosmo.LensingCosmology = ag.cosmo.Planck15(),
@@ -49,10 +49,10 @@ def __init__(
4949
----------
5050
dataset
5151
The imaging, interferometer or other dataset that the model if fitted too.
52-
positions_likelihood
53-
An object which alters the likelihood function to include a term which accounts for whether
54-
image-pixel coordinates in arc-seconds corresponding to the multiple images of the lensed source galaxy
55-
trace close to one another in the source-plane.
52+
positions_likelihood_list
53+
Alters the likelihood function to include a term which accounts for whether image-pixel coordinates in
54+
arc-seconds corresponding to the multiple images of each lensed source galaxy trace close to one another in
55+
their source-plane.
5656
adapt_images
5757
Contains the adapt-images which are used to make a pixelization's mesh and regularization adapt to the
5858
reconstructed galaxy's morphology.
@@ -78,7 +78,7 @@ def __init__(
7878

7979
AnalysisLens.__init__(
8080
self=self,
81-
positions_likelihood=positions_likelihood,
81+
positions_likelihood_list=positions_likelihood_list,
8282
cosmology=cosmology,
8383
)
8484

autolens/analysis/analysis/lens.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import logging
22
import numpy as np
3-
from typing import Dict, Optional, Union
3+
from typing import Dict, List, Optional, Union
44

55
import autofit as af
66
import autoarray as aa
@@ -22,8 +22,8 @@
2222
class AnalysisLens:
2323
def __init__(
2424
self,
25-
positions_likelihood: Optional[
26-
Union[PositionsLHResample, PositionsLHPenalty]
25+
positions_likelihood_list: Optional[
26+
List[Union[PositionsLHResample, PositionsLHPenalty]]
2727
] = None,
2828
cosmology: ag.cosmo.LensingCosmology = ag.cosmo.Planck15(),
2929
):
@@ -43,7 +43,7 @@ def __init__(
4343
The Cosmology assumed for this analysis.
4444
"""
4545
self.cosmology = cosmology
46-
self.positions_likelihood = positions_likelihood
46+
self.positions_likelihood_list = positions_likelihood_list
4747

4848
def tracer_via_instance_from(
4949
self,
@@ -123,10 +123,13 @@ def log_likelihood_positions_overwrite_from(
123123
The penalty value of the positions log likelihood, if the positions do not trace close in the source plane,
124124
else a None is returned to indicate there is no penalty.
125125
"""
126-
if self.positions_likelihood is not None:
126+
if self.positions_likelihood_list is not None:
127127
try:
128-
return self.positions_likelihood.log_likelihood_function_positions_overwrite(
129-
instance=instance, analysis=self
130-
)
128+
log_likelihood = 0.0
129+
for positions_likelihood in self.positions_likelihood_list:
130+
log_likelihood += positions_likelihood.log_likelihood_function_positions_overwrite(
131+
instance=instance, analysis=self
132+
)
133+
return log_likelihood
131134
except (ValueError, np.linalg.LinAlgError) as e:
132135
raise exc.FitException from e

autolens/analysis/positions.py

Lines changed: 53 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def __init__(
2626
self,
2727
threshold: float,
2828
positions: Optional[aa.Grid2DIrregular] = None,
29-
plane_redshift_positions_dict: Optional[Dict[float, aa.Grid2DIrregular]] = None,
29+
plane_redshift: Optional[float] = None,
3030
):
3131
"""
3232
The `PositionsLH` objects add a penalty term to the likelihood of the **PyAutoLens** `log_likelihood_function`
@@ -44,9 +44,8 @@ def __init__(
4444
The default behaviour assumes a single lens plane and single source plane, meaning the input `positions`
4545
are the image-plane coordinates of one source galaxy at a specifc redshift.
4646
47-
For multiple source planes, the `plane_redshift_positions_dict` dictionary can be used to input multiple
48-
sets of image positions, where the key is the redshift of the source plane and the value is the
49-
corresponding image-plane coordinates.
47+
For multiple source planes, the `plane_redshift` can be used to pair the image-plane positions with the
48+
redshift of the source plane they trace too.
5049
5150
Parameters
5251
----------
@@ -56,31 +55,21 @@ def __init__(
5655
threshold
5756
If the maximum separation of any two source plane coordinates is above the threshold the penalty term
5857
is applied.
59-
plane_redshift_positions_dict
60-
A dictionary of plane redshifts and the corresponding image-plane coordinates of the lensed source
61-
multiple images. The key is the redshift of the source plane and the value is the corresponding
62-
image-plane coordinates.
58+
plane_redshift
59+
The plane redshift of the lensed source multiple images, which is only required if position threshold
60+
for a double source plane lens system is being used where the specific plane is required.
6361
"""
6462

6563
self.positions = positions
6664
self.threshold = threshold
65+
self.plane_redshift = plane_redshift
6766

68-
self.plane_redshift_positions_dict = plane_redshift_positions_dict
69-
70-
if plane_redshift_positions_dict is None:
71-
self.plane_redshift_positions_dict = {None: positions}
72-
73-
if len(self.plane_redshift_positions_dict) == 1:
74-
self.positions = list(self.plane_redshift_positions_dict.values())[0]
75-
76-
for positions in self.plane_redshift_positions_dict.values():
77-
78-
if len(positions) == 1:
79-
raise exc.PositionsException(
80-
f"The positions input into the PositionsLikelihood object have length one "
81-
f"(e.g. it is only one (y,x) coordinate and therefore cannot be compared with other images).\n\n"
82-
"Please input more positions into the Positions."
83-
)
67+
if len(positions) == 1:
68+
raise exc.PositionsException(
69+
f"The positions input into the PositionsLikelihood object have length one "
70+
f"(e.g. it is only one (y,x) coordinate and therefore cannot be compared with other images).\n\n"
71+
"Please input more positions into the Positions."
72+
)
8473

8574
def log_likelihood_function_positions_overwrite(
8675
self, instance: af.ModelInstance, analysis: AnalysisDataset
@@ -107,29 +96,22 @@ def output_positions_info(self, output_path: str, tracer: Tracer):
10796
"""
10897
with open_(path.join(output_path, "positions.info"), "w+") as f:
10998

110-
plane_index = 0
111-
112-
for plane_redshift, positions in self.plane_redshift_positions_dict.items():
113-
114-
positions_fit = SourceMaxSeparation(
115-
data=positions, noise_map=None, tracer=tracer, plane_redshift=plane_redshift
116-
)
117-
118-
distances = positions_fit.data.distances_to_coordinate_from(
119-
coordinate=(0.0, 0.0)
120-
)
99+
positions_fit = SourceMaxSeparation(
100+
data=self.positions, noise_map=None, tracer=tracer, plane_redshift=self.plane_redshift
101+
)
121102

122-
f.write(f"Plane Index: {plane_index} \n")
123-
f.write(f"Plane Redshift: {plane_redshift} \n")
124-
f.write(f"Positions: \n {positions} \n\n")
125-
f.write(f"Radial Distance from (0.0, 0.0): \n {distances} \n\n")
126-
f.write(f"Threshold = {self.threshold} \n")
127-
f.write(
128-
f"Max Source Plane Separation of Maximum Likelihood Model = {positions_fit.max_separation_of_plane_positions}"
129-
)
130-
f.write("")
103+
distances = positions_fit.data.distances_to_coordinate_from(
104+
coordinate=(0.0, 0.0)
105+
)
131106

132-
plane_index += 1
107+
f.write(f"Plane Redshift: {self.plane_redshift} \n")
108+
f.write(f"Positions: \n {self.positions} \n\n")
109+
f.write(f"Radial Distance from (0.0, 0.0): \n {distances} \n\n")
110+
f.write(f"Threshold = {self.threshold} \n")
111+
f.write(
112+
f"Max Source Plane Separation of Maximum Likelihood Model = {positions_fit.max_separation_of_plane_positions}"
113+
)
114+
f.write("")
133115

134116

135117
class PositionsLHResample(AbstractPositionsLH):
@@ -179,20 +161,18 @@ def log_likelihood_function_positions_overwrite(
179161
if not tracer.has(cls=ag.mp.MassProfile) or len(tracer.planes) == 1:
180162
return
181163

182-
for plane_redshift, positions in self.plane_redshift_positions_dict.items():
183-
184-
positions_fit = SourceMaxSeparation(
185-
data=positions,
186-
noise_map=None,
187-
tracer=tracer,
188-
plane_redshift=plane_redshift,
189-
)
164+
positions_fit = SourceMaxSeparation(
165+
data=self.positions,
166+
noise_map=None,
167+
tracer=tracer,
168+
plane_redshift=self.plane_redshift,
169+
)
190170

191-
if not positions_fit.max_separation_within_threshold(self.threshold):
192-
if os.environ.get("PYAUTOFIT_TEST_MODE") == "1":
193-
return
171+
if not positions_fit.max_separation_within_threshold(self.threshold):
172+
if os.environ.get("PYAUTOFIT_TEST_MODE") == "1":
173+
return
194174

195-
raise exc.RayTracingException
175+
raise exc.RayTracingException
196176

197177

198178
class PositionsLHPenalty(AbstractPositionsLH):
@@ -201,7 +181,7 @@ def __init__(
201181
threshold: float,
202182
log_likelihood_penalty_factor: float = 1e8,
203183
positions: Optional[aa.Grid2DIrregular] = None,
204-
plane_redshift_positions_dict: Optional[Dict[int, aa.Grid2DIrregular]] = None,
184+
plane_redshift: Optional[float] = None,
205185
):
206186
"""
207187
The `PositionsLH` objects add a penalty term to the likelihood of the **PyAutoLens** `log_likelihood_function`
@@ -231,15 +211,14 @@ def __init__(
231211
log_likelihood_penalty_factor
232212
A factor which multiplies how far source pixels do not trace within the threshold of one another, with a
233213
larger factor producing a larger penalty making the non-linear parameter space gradient steeper.
234-
plane_redshift_positions_dict
235-
A dictionary of plane redshifts and the corresponding image-plane coordinates of the lensed source
236-
multiple images. The key is the redshift of the source plane and the value is the corresponding
237-
image-plane coordinates.
214+
plane_redshift
215+
The plane redshift of the lensed source multiple images, which is only required if position threshold
216+
for a double source plane lens system is being used where the specific plane is required.
238217
"""
239218
super().__init__(
240219
positions=positions,
241220
threshold=threshold,
242-
plane_redshift_positions_dict=plane_redshift_positions_dict,
221+
plane_redshift=plane_redshift
243222
)
244223

245224
self.log_likelihood_penalty_factor = log_likelihood_penalty_factor
@@ -318,21 +297,19 @@ def log_likelihood_penalty_from(self, tracer: Tracer) -> Optional[float]:
318297

319298
log_likelihood_penalty = 0.0
320299

321-
for plane_redshift, positions in self.plane_redshift_positions_dict.items():
322-
323-
positions_fit = SourceMaxSeparation(
324-
data=positions,
325-
noise_map=None,
326-
tracer=tracer,
327-
plane_redshift=plane_redshift,
328-
)
300+
positions_fit = SourceMaxSeparation(
301+
data=self.positions,
302+
noise_map=None,
303+
tracer=tracer,
304+
plane_redshift=self.plane_redshift,
305+
)
329306

330-
if not positions_fit.max_separation_within_threshold(self.threshold):
307+
if not positions_fit.max_separation_within_threshold(self.threshold):
331308

332-
log_likelihood_penalty += self.log_likelihood_penalty_factor * (
333-
positions_fit.max_separation_of_plane_positions
334-
- self.threshold
335-
)
309+
log_likelihood_penalty += self.log_likelihood_penalty_factor * (
310+
positions_fit.max_separation_of_plane_positions
311+
- self.threshold
312+
)
336313

337314
return log_likelihood_penalty
338315

test_autolens/imaging/model/test_analysis_imaging.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test__positions__resample__raises_exception(masked_imaging_7x7):
5757
)
5858

5959
analysis = al.AnalysisImaging(
60-
dataset=masked_imaging_7x7, positions_likelihood=positions_likelihood
60+
dataset=masked_imaging_7x7, positions_likelihood_list=[positions_likelihood]
6161
)
6262

6363
instance = model.instance_from_unit_vector([])
@@ -89,7 +89,7 @@ def test__positions__likelihood_overwrites__changes_likelihood(masked_imaging_7x
8989
)
9090

9191
analysis = al.AnalysisImaging(
92-
dataset=masked_imaging_7x7, positions_likelihood=positions_likelihood
92+
dataset=masked_imaging_7x7, positions_likelihood_list=[positions_likelihood]
9393
)
9494
analysis_log_likelihood = analysis.log_likelihood_function(instance=instance)
9595

@@ -116,17 +116,15 @@ def test__positions__likelihood_overwrites__changes_likelihood__double_source_pl
116116

117117
instance = model.instance_from_unit_vector([])
118118

119-
plane_redshift_positions_dict = {
120-
1.0: al.Grid2DIrregular([(1.0, 100.0), (200.0, 2.0)]),
121-
2.0: al.Grid2DIrregular([(1.0, 100.0), (200.0, 2.0)])
122-
}
123-
124-
positions_likelihood = al.PositionsLHPenalty(
125-
plane_redshift_positions_dict=plane_redshift_positions_dict, threshold=0.01
119+
positions_likelihood_0 = al.PositionsLHPenalty(
120+
plane_redshift=1.0, positions=al.Grid2DIrregular([(1.0, 100.0), (200.0, 2.0)]), threshold=0.01
121+
)
122+
positions_likelihood_1 = al.PositionsLHPenalty(
123+
plane_redshift=2.0, positions=al.Grid2DIrregular([(1.0, 100.0), (200.0, 2.0)]), threshold=0.01
126124
)
127125

128126
analysis = al.AnalysisImaging(
129-
dataset=masked_imaging_7x7, positions_likelihood=positions_likelihood
127+
dataset=masked_imaging_7x7, positions_likelihood_list=[positions_likelihood_0, positions_likelihood_1]
130128
)
131129
analysis_log_likelihood = analysis.log_likelihood_function(instance=instance)
132130

0 commit comments

Comments
 (0)