Skip to content

Commit 52420b3

Browse files
authored
Merge pull request #197 from Jammy2211/feature/image_mesh_jax
Feature/image mesh jax
2 parents f36ea41 + a3015a3 commit 52420b3

File tree

14 files changed

+208
-228
lines changed

14 files changed

+208
-228
lines changed

autoarray/inversion/inversion/settings.py

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,6 @@ def __init__(
1717
no_regularization_add_to_curvature_diag_value: float = None,
1818
use_w_tilde_numpy: bool = False,
1919
use_source_loop: bool = False,
20-
image_mesh_min_mesh_pixels_per_pixel=None,
21-
image_mesh_min_mesh_number: int = 5,
22-
image_mesh_adapt_background_percent_threshold: float = None,
23-
image_mesh_adapt_background_percent_check: float = 0.8,
2420
tolerance: float = 1e-8,
2521
maxiter: int = 250,
2622
):
@@ -46,19 +42,6 @@ def __init__(
4642
which exploit sparsity to do the calculation normally in a more efficient way).
4743
use_source_loop
4844
Shhhh its a secret.
49-
image_mesh_min_mesh_pixels_per_pixel
50-
If not None, the image-mesh must place this many mesh pixels per image pixels in the N highest weighted
51-
regions of the adapt data, or an `InversionException` is raised. This can be used to force the image-mesh
52-
to cluster large numbers of source pixels to the adapt-datas brightest regions.
53-
image_mesh_min_mesh_number
54-
The value N given above in the docstring for `image_mesh_min_mesh_pixels_per_pixel`, indicating how many
55-
image pixels are checked for having a threshold number of mesh pixels.
56-
image_mesh_adapt_background_percent_threshold
57-
If not None, the image-mesh must place this percentage of mesh-pixels in the background regions of the
58-
`adapt_data`, where the background is the `image_mesh_adapt_background_percent_check` masked data pixels
59-
with the lowest values.
60-
image_mesh_adapt_background_percent_check
61-
The percentage of masked data pixels which are checked for the background criteria.
6245
tolerance
6346
For an interferometer inversion using the linear operators method, sets the tolerance of the solver
6447
(this input does nothing for dataset data and other interferometer methods).
@@ -73,14 +56,6 @@ def __init__(
7356
self._no_regularization_add_to_curvature_diag_value = (
7457
no_regularization_add_to_curvature_diag_value
7558
)
76-
self.image_mesh_min_mesh_pixels_per_pixel = image_mesh_min_mesh_pixels_per_pixel
77-
self.image_mesh_min_mesh_number = image_mesh_min_mesh_number
78-
self.image_mesh_adapt_background_percent_threshold = (
79-
image_mesh_adapt_background_percent_threshold
80-
)
81-
self.image_mesh_adapt_background_percent_check = (
82-
image_mesh_adapt_background_percent_check
83-
)
8459

8560
self.tolerance = tolerance
8661
self.maxiter = maxiter

autoarray/inversion/mock/mock_image_mesh.py

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,3 @@ def __init__(self, image_plane_mesh_grid=None):
1212
super().__init__()
1313

1414
self.image_plane_mesh_grid = image_plane_mesh_grid
15-
16-
def image_plane_mesh_grid_from(
17-
self, mask: Mask2D, adapt_data: Optional[np.ndarray], settings=None
18-
) -> Grid2DIrregular:
19-
if adapt_data is not None and self.image_plane_mesh_grid is not None:
20-
return adapt_data * self.image_plane_mesh_grid
21-
22-
return self.image_plane_mesh_grid
23-
24-
@property
25-
def uses_adapt_images(self) -> bool:
26-
return False

autoarray/inversion/mock/mock_mesh.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,8 @@ def image_plane_mesh_grid_from(
3737
self,
3838
mask: Mask2D,
3939
adapt_data,
40-
settings=None,
4140
):
4241
if adapt_data is not None and self.image_plane_mesh_grid is not None:
4342
return adapt_data * self.image_plane_mesh_grid
4443

4544
return self.image_plane_mesh_grid
46-
47-
@property
48-
def requires_image_mesh(self):
49-
return False

autoarray/inversion/mock/mock_pixelization.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,10 @@ def __init__(
77
self,
88
mesh=None,
99
regularization=None,
10-
image_mesh=None,
1110
mapper=None,
1211
image_plane_mesh_grid=None,
1312
):
14-
super().__init__(
15-
mesh=mesh, regularization=regularization, image_mesh=image_mesh
16-
)
13+
super().__init__(mesh=mesh, regularization=regularization)
1714

1815
self.mapper = mapper
1916
self.image_plane_mesh_grid = image_plane_mesh_grid

autoarray/inversion/pixelization/image_mesh/abstract.py

Lines changed: 1 addition & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def __init__(self):
1818
"""
1919
An abstract image mesh, which is used by pixelizations to determine the (y,x) mesh coordinates from image
2020
data.
21+
2122
"""
2223
pass
2324

@@ -29,7 +30,6 @@ def image_plane_mesh_grid_from(
2930
self,
3031
mask: Mask2D,
3132
adapt_data: Optional[np.ndarray] = None,
32-
settings: SettingsInversion = None,
3333
) -> Grid2DIrregular:
3434
raise NotImplementedError
3535

@@ -65,131 +65,3 @@ def mesh_pixels_per_image_pixels_from(
6565
)
6666

6767
return Array2D(values=mesh_pixels_per_image_pixels, mask=mask)
68-
69-
def check_mesh_pixels_per_image_pixels(
70-
self, mask: Mask2D, mesh_grid: Grid2DIrregular, settings: SettingsInversion
71-
):
72-
"""
73-
Checks the number of mesh pixels in every image pixel and raises an `InversionException` if there are fewer
74-
mesh pixels inside a certain number of image-pixels than the input settings.
75-
76-
This allows a user to force a model-fit to use image-mesh's which cluster a large number of mesh pixels to
77-
the brightest regions of the image data (E.g. the highst weighted regions).
78-
79-
The check works as follows:
80-
81-
1) Compute the 2D array of the number of mesh pixels in every masked data image pixel.
82-
2) Find the number of mesh pixels in the N data pixels with the larger number of mesh pixels, where N is
83-
given by `settings.image_mesh_min_mesh_number`. For example, if `settings.image_mesh_min_mesh_number=5` then
84-
the number of mesh pixels in the 5 data pixels with the most data pixels is computed.
85-
3) Compare the lowest value above to the value `settings.image_mesh_min_mesh_pixels_per_pixel`. If the value is
86-
below this value, raise an `InversionException`.
87-
88-
Therefore, by settings `settings.image_mesh_min_mesh_pixels_per_pixel` to a value above 1 the code is forced
89-
to adapt the image mesh enough to put many mesh pixels in the brightest image pixels.
90-
91-
Parameters
92-
----------
93-
mask
94-
The mask of the dataset being analysed, which the pixelization grid maps too. The number of
95-
mesh pixels mapped inside each of this mask's image-pixels is returned.
96-
mesh_grid
97-
The image mesh-grid computed by the class which adapts to the data's mask. The number of image mesh pixels
98-
that fall within each of the data's mask pixels is returned.
99-
settings
100-
The inversion settings, which have the criteria dictating if the image-mesh has clustered enough or if
101-
an exception is raised.
102-
"""
103-
104-
if os.environ.get("PYAUTOFIT_TEST_MODE") == "1":
105-
return
106-
107-
if settings is not None:
108-
if settings.image_mesh_min_mesh_pixels_per_pixel is not None:
109-
mesh_pixels_per_image_pixels = self.mesh_pixels_per_image_pixels_from(
110-
mask=mask, mesh_grid=mesh_grid
111-
)
112-
113-
indices_of_highest_values = np.argsort(mesh_pixels_per_image_pixels)[
114-
-settings.image_mesh_min_mesh_number :
115-
]
116-
lowest_mesh_pixels = np.min(
117-
mesh_pixels_per_image_pixels[indices_of_highest_values]
118-
)
119-
120-
if lowest_mesh_pixels < settings.image_mesh_min_mesh_pixels_per_pixel:
121-
raise exc.InversionException()
122-
123-
return mesh_grid
124-
125-
def check_adapt_background_pixels(
126-
self,
127-
mask: Mask2D,
128-
mesh_grid: Grid2DIrregular,
129-
adapt_data: Optional[np.ndarray],
130-
settings: SettingsInversion,
131-
):
132-
"""
133-
Checks the number of mesh pixels in the background of the image-mesh and raises an `InversionException` if
134-
there are fewer mesh pixels in the background than the input settings.
135-
136-
This allows a user to force a model-fit to use image-mesh's which cluster a minimum number of mesh pixels to
137-
the faintest regions of the image data (E.g. the lowest weighted regions). This prevents too few image-mesh
138-
pixels being allocated to the background of the data.
139-
140-
The check works as follows:
141-
142-
1) Find all pixels in the background of the `adapt_data`, which are N pixels with the lowest values, where N is
143-
a percentage given by `settings.image_mesh_adapt_background_percent_check`. If N is 50%, then the half of
144-
pixels in `adapt_data` with the lowest values will be checked.
145-
2) Sum the total number of mesh pixels in these background pixels, thereby estimating the number of mesh pixels
146-
assigned to background pixels.
147-
3) Compare this value to the total number of mesh pixels multiplied
148-
by `settings.image_mesh_adapt_background_percent_threshold` and raise an `InversionException` if the number
149-
of mesh pixels is below this value, meaning the background did not have sufficient mesh pixels in it.
150-
151-
Therefore, by setting `settings.image_mesh_adapt_background_percent_threshold` the code is forced
152-
to adapt the image mesh in a way that places many mesh pixels in the background regions.
153-
154-
Parameters
155-
----------
156-
mask
157-
The mask of the dataset being analysed, which the pixelization grid maps too. The number of
158-
mesh pixels mapped inside each of this mask's image-pixels is returned.
159-
mesh_grid
160-
The image mesh-grid computed by the class which adapts to the data's mask. The number of image mesh pixels
161-
that fall within each of the data's mask pixels is returned.
162-
adapt_data
163-
A image which represents one or more components in the masked 2D data in the image-plane.
164-
settings
165-
The inversion settings, which have the criteria dictating if the image-mesh has clustered enough or if
166-
an exception is raised.
167-
"""
168-
169-
if os.environ.get("PYAUTOFIT_TEST_MODE") == "1":
170-
return
171-
172-
if settings is not None:
173-
if settings.image_mesh_adapt_background_percent_threshold is not None:
174-
pixels = mesh_grid.shape[0]
175-
176-
pixels_in_background = int(
177-
mask.shape_slim * settings.image_mesh_adapt_background_percent_check
178-
)
179-
180-
indices_of_lowest_values = np.argsort(adapt_data)[:pixels_in_background]
181-
mask_background = np.zeros_like(adapt_data, dtype=bool)
182-
mask_background[indices_of_lowest_values] = True
183-
184-
mesh_pixels_per_image_pixels = self.mesh_pixels_per_image_pixels_from(
185-
mask=mask, mesh_grid=mesh_grid
186-
)
187-
188-
mesh_pixels_in_background = sum(
189-
mesh_pixels_per_image_pixels[mask_background]
190-
)
191-
192-
if mesh_pixels_in_background < (
193-
pixels * settings.image_mesh_adapt_background_percent_threshold
194-
):
195-
raise exc.InversionException()

0 commit comments

Comments
 (0)