11from __future__ import annotations
22from typing import TYPE_CHECKING , Dict , Optional
33
4+ import numpy as np
5+
46from autofit import ModelInstance
57
68if TYPE_CHECKING :
1315
1416
1517class AbstractFitInversion :
16- def __init__ (
17- self ,
18- model_obj ,
19- settings_inversion : aa .SettingsInversion ,
20- ):
18+ def __init__ (self , model_obj , settings : aa .Settings , xp = np ):
2119 """
2220 An abstract fit object which fits to datasets (e.g. imaging, interferometer) inherit from.
2321
@@ -30,11 +28,20 @@ def __init__(
3028 The object which contains the model components (e.g. light profiles, galaxies, etc) which are used to
3129 create the model-data that fits the data. In PyAutoGalaxy this is a list of galaxies and PyAutoLens
3230 it is a `Tracer`.
33- settings_inversion
31+ settings
3432 Settings controlling how an inversion is fitted for example which linear algebra formalism is used.
3533 """
3634 self .model_obj = model_obj
37- self .settings_inversion = settings_inversion
35+ self .settings = settings or aa .Settings ()
36+ self .use_jax = xp is not np
37+
38+ @property
39+ def _xp (self ):
40+ if self .use_jax :
41+ import jax .numpy as jnp
42+
43+ return jnp
44+ return np
3845
3946 @property
4047 def total_mappers (self ) -> int :
@@ -68,7 +75,7 @@ def perform_inversion(self) -> bool:
6875 def sparse_operator (self ) -> Optional [aa .ImagingSparseOperator ]:
6976 """
7077 Only call the `sparse_operator` property of a dataset used to perform efficient linear algebra calculations if
71- the SettingsInversion ()` object has `use_sparse_operator=True`, to avoid unnecessary computation.
78+ the Settings ()` object has `use_sparse_operator=True`, to avoid unnecessary computation.
7279
7380 Returns
7481 -------
@@ -95,6 +102,14 @@ def linear_light_profile_intensity_dict(
95102
96103 This function returns a dictionary which maps every linear light profile instance to its solved for
97104 `intensity` value in the inversion, so that the intensity value of every light profile can be accessed.
105+
106+ Type casting is complicated by JAX. When this function is used in a JAX.jit (e.g. computed latent varialbes)
107+ it requires the reconstruction values to be JAX arrays, but when it is used outside of JAX certain taks
108+ requires the reconstruction values to be floats.
109+
110+ An example of the latter is using a tracer inferred in one search to pass the solved for intensity values of
111+ linear light profiles to a subsequent search, for example setting up the intensities of the mass components
112+ of a light dark model.
98113 """
99114
100115 if self .inversion is None :
@@ -110,12 +125,20 @@ def linear_light_profile_intensity_dict(
110125 reconstruction = self .inversion .reconstruction_dict [linear_obj_func ]
111126
112127 for i , light_profile in enumerate (linear_obj_func .light_profile_list ):
113- linear_light_profile_intensity_dict [light_profile ] = reconstruction [i ]
128+ if self .use_jax :
129+ linear_light_profile_intensity_dict [light_profile ] = reconstruction [
130+ i
131+ ]
132+ else :
133+ linear_light_profile_intensity_dict [light_profile ] = float (
134+ reconstruction [i ]
135+ )
114136
115137 return linear_light_profile_intensity_dict
116138
117139 def galaxy_linear_obj_data_dict_from (
118- self , use_image : bool = False
140+ self ,
141+ use_operated : bool = True ,
119142 ) -> Dict [Galaxy , aa .Array2D ]:
120143 """
121144 Returns a dictionary mapping every galaxy containing a linear
@@ -127,16 +150,17 @@ def galaxy_linear_obj_data_dict_from(
127150 This is used to create the overall `galaxy_model_image_dict`, which maps every galaxy to its
128151 overall `model_data` (e.g. including the `model_data` of orindary light profiles too).
129152
130- If `use_image =False`, the `reconstructed_data` of the inversion (e.g. an image for dataset data,
153+ If `use_operated =False`, the `reconstructed_data` of the inversion (e.g. an image for dataset data,
131154 visibilities for interferometer data) is input in the dictionary.
132155
133- if `use_image =True`, the `reconstructed_image ` of the inversion (e.g. the image for dataset data, the
156+ if `use_operated =True`, the `reconstructed_operated_data ` of the inversion (e.g. the image for dataset data, the
134157 real-space image for interferometer data) is input in the dictionary.
135158
136159 Parameters
137160 ----------
138- use_image
139- Whether to put the reconstructed data or images in the dictionary.
161+ use_operated
162+ Whether to use the operated (e.g PSF convolved) images of the linear objects in the dictionary, or
163+ the unoperated images.
140164
141165 Returns
142166 -------
@@ -154,13 +178,12 @@ def galaxy_linear_obj_data_dict_from(
154178 except KeyError :
155179 continue
156180
157- if not use_image :
158- mapped_reconstructed = self .inversion .mapped_reconstructed_data_dict [
159- linear_obj
160- ]
161-
181+ if use_operated :
182+ mapped_reconstructed = (
183+ self .inversion .mapped_reconstructed_operated_data_dict [linear_obj ]
184+ )
162185 else :
163- mapped_reconstructed = self .inversion .mapped_reconstructed_image_dict [
186+ mapped_reconstructed = self .inversion .mapped_reconstructed_data_dict [
164187 linear_obj
165188 ]
166189
0 commit comments