1+ import jax .numpy as jnp
2+
3+ from autoconf import cached_property
4+
5+ from autoarray .inversion .pixelization .mappers .rectangular import MapperRectangular
6+ from autoarray .inversion .pixelization .mappers .abstract import PixSubWeights
7+
8+ from autoarray .inversion .pixelization .mappers import mapper_util
9+
10+
11+ class MapperRectangularUniform (MapperRectangular ):
12+ """
13+ To understand a `Mapper` one must be familiar `Mesh` objects and the `mesh` and `pixelization` packages, where
14+ the four grids grouped in a `MapperGrids` object are explained (`image_plane_data_grid`, `source_plane_data_grid`,
15+ `image_plane_mesh_grid`,`source_plane_mesh_grid`)
16+
17+ If you are unfamliar withe above objects, read through the docstrings of the `pixelization`, `mesh` and
18+ `mapper_grids` packages.
19+
20+ A `Mapper` determines the mappings between the masked data grid's pixels (`image_plane_data_grid` and
21+ `source_plane_data_grid`) and the mesh's pixels (`image_plane_mesh_grid` and `source_plane_mesh_grid`).
22+
23+ The 1D Indexing of each grid is identical in the `data` and `source` frames (e.g. the transformation does not
24+ change the indexing, such that `source_plane_data_grid[0]` corresponds to the transformed value
25+ of `image_plane_data_grid[0]` and so on).
26+
27+ A mapper therefore only needs to determine the index mappings between the `grid_slim` and `mesh_grid`,
28+ noting that associations are made by pairing `source_plane_mesh_grid` with `source_plane_data_grid`.
29+
30+ Mappings are represented in the 2D ndarray `pix_indexes_for_sub_slim_index`, whereby the index of
31+ a pixel on the `mesh_grid` maps to the index of a pixel on the `grid_slim` as follows:
32+
33+ - pix_indexes_for_sub_slim_index[0, 0] = 0: the data's 1st sub-pixel maps to the mesh's 1st pixel.
34+ - pix_indexes_for_sub_slim_index[1, 0] = 3: the data's 2nd sub-pixel maps to the mesh's 4th pixel.
35+ - pix_indexes_for_sub_slim_index[2, 0] = 1: the data's 3rd sub-pixel maps to the mesh's 2nd pixel.
36+
37+ The second dimension of this array (where all three examples above are 0) is used for cases where a
38+ single pixel on the `grid_slim` maps to multiple pixels on the `mesh_grid`. For example, a
39+ `Delaunay` triangulation, where every `grid_slim` pixel maps to three Delaunay pixels (the corners of the
40+ triangles) with varying interpolation weights .
41+
42+ For a `Rectangular` mesh every pixel in the masked data maps to only one pixel, thus the second
43+ dimension of `pix_indexes_for_sub_slim_index` is always of size 1.
44+
45+ The mapper allows us to create a mapping matrix, which is a matrix representing the mapping between every
46+ unmasked data pixel annd the pixels of a mesh. This matrix is the basis of performing an `Inversion`,
47+ which reconstructs the data using the `source_plane_mesh_grid`.
48+
49+ Parameters
50+ ----------
51+ mapper_grids
52+ An object containing the data grid and mesh grid in both the data-frame and source-frame used by the
53+ mapper to map data-points to linear object parameters.
54+ regularization
55+ The regularization scheme which may be applied to this linear object in order to smooth its solution,
56+ which for a mapper smooths neighboring pixels on the mesh.
57+ """
58+
59+ @cached_property
60+ def pix_sub_weights (self ) -> PixSubWeights :
61+ """
62+ Computes the following three quantities describing the mappings between of every sub-pixel in the masked data
63+ and pixel in the `Rectangular` mesh.
64+
65+ - `pix_indexes_for_sub_slim_index`: the mapping of every data pixel (given its `sub_slim_index`)
66+ to mesh pixels (given their `pix_indexes`).
67+
68+ - `pix_sizes_for_sub_slim_index`: the number of mappings of every data pixel to mesh pixels.
69+
70+ - `pix_weights_for_sub_slim_index`: the interpolation weights of every data pixel's mesh
71+ pixel mapping
72+
73+ These are packaged into the class `PixSubWeights` with attributes `mappings`, `sizes` and `weights`.
74+
75+ The `sub_slim_index` refers to the masked data sub-pixels and `pix_indexes` the mesh pixel indexes,
76+ for example:
77+
78+ - `pix_indexes_for_sub_slim_index[0, 0] = 2`: The data's first (index 0) sub-pixel maps to the Rectangular
79+ mesh's third (index 2) pixel.
80+
81+ - `pix_indexes_for_sub_slim_index[2, 0] = 4`: The data's third (index 2) sub-pixel maps to the Rectangular
82+ mesh's fifth (index 4) pixel.
83+
84+ The second dimension of the array `pix_indexes_for_sub_slim_index`, which is 0 in both examples above, is used
85+ for cases where a data pixel maps to more than one mesh pixel (for example a `Delaunay` triangulation
86+ where each data pixel maps to 3 Delaunay triangles with interpolation weights). The weights of multiple mappings
87+ are stored in the array `pix_weights_for_sub_slim_index`.
88+
89+ For a Rectangular pixelization each data sub-pixel maps to a single mesh pixel, thus the second
90+ dimension of the array `pix_indexes_for_sub_slim_index` 1 and all entries in `pix_weights_for_sub_slim_index`
91+ are equal to 1.0.
92+ """
93+
94+ mappings , weights = (
95+ mapper_util .rectangular_mappings_weights_via_interpolation_from (
96+ shape_native = self .shape_native ,
97+ source_plane_mesh_grid = self .source_plane_mesh_grid .array ,
98+ source_plane_data_grid = self .source_plane_data_grid .over_sampled ,
99+ )
100+ )
101+
102+ return PixSubWeights (
103+ mappings = mappings ,
104+ sizes = 4 * jnp .ones (len (mappings ), dtype = "int" ),
105+ weights = weights ,
106+ )
0 commit comments