return (coefficients[<NUM_LIT:0>] * pixel_signals + coefficients[<NUM_LIT:1>] * (<NUM_LIT:1.0> - pixel_signals)) ** <NUM_LIT><EOL>

Compute the regularization weights, which are the effective regularization coefficient of every \
    pixel. They are computed using the (scaled) pixel-signal of each pixel.

    Two regularization coefficients are used, corresponding to the:

    1) (pixel_signals) - pixels with a high pixel-signal (i.e. where the signal is located in the pixelization).
    2) (1.0 - pixel_signals) - pixels with a low pixel-signal (i.e. where the signal is not located in the \
     pixelization).

    Parameters
    ----------
    coefficients : (float, float)
        The regularization coefficients which controls the degree of smoothing of the inversion reconstruction.
    pixel_signals : ndarray
        The estimated signal in every pixelization pixel, used to change the regularization weighting of high signal \
        and low signal pixelizations.


pixels = len(regularization_weights)<EOL>regularization_matrix = np.zeros(shape=(pixels, pixels))<EOL>regularization_weight = regularization_weights ** <NUM_LIT><EOL>for i in range(pixels):<EOL><INDENT>for j in range(pixel_neighbors_size[i]):<EOL><INDENT>neighbor_index = pixel_neighbors[i, j]<EOL>regularization_matrix[i, i] += regularization_weight[neighbor_index]<EOL>regularization_matrix[neighbor_index, neighbor_index] += regularization_weight[neighbor_index]<EOL>regularization_matrix[i, neighbor_index] -= regularization_weight[neighbor_index]<EOL>regularization_matrix[neighbor_index, i] -= regularization_weight[neighbor_index]<EOL><DEDENT><DEDENT>return regularization_matrix<EOL>

From the pixel-neighbors, setup the regularization matrix using the weighted regularization scheme.

    Parameters
    ----------
    regularization_weights : ndarray
        The regularization_ weight of each pixel, which governs how much smoothing is applied to that individual pixel.
    pixel_neighbors : ndarray
        An array of length (total_pixels) which provides the index of all neighbors of every pixel in \
        the Voronoi grid (entries of -1 correspond to no neighbor).
    pixel_neighbors_size : ndarrayy
        An array of length (total_pixels) which gives the number of neighbors of every pixel in the \
        Voronoi grid.


pixels = shape[<NUM_LIT:0>]*shape[<NUM_LIT:1>]<EOL>pixel_neighbors = -<NUM_LIT:1> * np.ones(shape=(pixels, <NUM_LIT:4>))<EOL>pixel_neighbors_size = np.zeros(pixels)<EOL>pixel_neighbors, pixel_neighbors_size = compute_corner_neighbors(pixel_neighbors, pixel_neighbors_size,<EOL>shape, pixels)<EOL>pixel_neighbors, pixel_neighbors_size = compute_top_edge_neighbors(pixel_neighbors, pixel_neighbors_size,<EOL>shape, pixels)<EOL>pixel_neighbors, pixel_neighbors_size = compute_left_edge_neighbors(pixel_neighbors, pixel_neighbors_size,<EOL>shape, pixels)<EOL>pixel_neighbors, pixel_neighbors_size = compute_right_edge_neighbors(pixel_neighbors, pixel_neighbors_size,<EOL>shape, pixels)<EOL>pixel_neighbors, pixel_neighbors_size = compute_bottom_edge_neighbors(pixel_neighbors, pixel_neighbors_size,<EOL>shape, pixels)<EOL>pixel_neighbors, pixel_neighbors_size = compute_central_neighbors(pixel_neighbors, pixel_neighbors_size,<EOL>shape, pixels)<EOL>return pixel_neighbors, pixel_neighbors_size<EOL>

Compute the neighbors of every pixel as a list of the pixel index's each pixel shares a vertex with.

    The uniformity of the rectangular grid's geometry is used to compute this.


pixel_neighbors_size = np.zeros(shape=(pixels))<EOL>for ridge_index in range(ridge_points.shape[<NUM_LIT:0>]):<EOL><INDENT>pair0 = ridge_points[ridge_index, <NUM_LIT:0>]<EOL>pair1 = ridge_points[ridge_index, <NUM_LIT:1>]<EOL>pixel_neighbors_size[pair0] += <NUM_LIT:1><EOL>pixel_neighbors_size[pair1] += <NUM_LIT:1><EOL><DEDENT>pixel_neighbors_index = np.zeros(shape=(pixels))<EOL>pixel_neighbors = -<NUM_LIT:1> * np.ones(shape=(pixels, int(np.max(pixel_neighbors_size))))<EOL>for ridge_index in range(ridge_points.shape[<NUM_LIT:0>]):<EOL><INDENT>pair0 = ridge_points[ridge_index, <NUM_LIT:0>]<EOL>pair1 = ridge_points[ridge_index, <NUM_LIT:1>]<EOL>pixel_neighbors[pair0, int(pixel_neighbors_index[pair0])] = pair1<EOL>pixel_neighbors[pair1, int(pixel_neighbors_index[pair1])] = pair0<EOL>pixel_neighbors_index[pair0] += <NUM_LIT:1><EOL>pixel_neighbors_index[pair1] += <NUM_LIT:1><EOL><DEDENT>return pixel_neighbors, pixel_neighbors_size<EOL>

Compute the neighbors of every pixel as a list of the pixel index's each pixel shares a vertex with.

    The ridge points of the Voronoi grid are used to derive this.

    Parameters
    ----------
    ridge_points : scipy.spatial.Voronoi.ridge_points
        Each Voronoi-ridge (two indexes representing a pixel mapping_matrix).


mapping_shape = blurred_mapping_matrix.shape<EOL>data_vector = np.zeros(mapping_shape[<NUM_LIT:1>])<EOL>for image_index in range(mapping_shape[<NUM_LIT:0>]):<EOL><INDENT>for pix_index in range(mapping_shape[<NUM_LIT:1>]):<EOL><INDENT>data_vector[pix_index] += image_1d[image_index] *blurred_mapping_matrix[image_index, pix_index] / (noise_map_1d[image_index] ** <NUM_LIT>)<EOL><DEDENT><DEDENT>return data_vector<EOL>

Compute the hyper vector *D* from a blurred mapping matrix *f* and the 1D image *d* and 1D noise-map *\sigma* \
    (see Warren & Dye 2003).

    Parameters
    -----------
    blurred_mapping_matrix : ndarray
        The matrix representing the blurred mappings between sub-grid pixels and pixelization pixels.
    image_1d : ndarray
        Flattened 1D array of the observed image the inversion is fitting.
    noise_map_1d : ndarray
        Flattened 1D array of the noise-map used by the inversion during the fit.


flist = np.zeros(blurred_mapping_matrix.shape[<NUM_LIT:0>])<EOL>iflist = np.zeros(blurred_mapping_matrix.shape[<NUM_LIT:0>], dtype='<STR_LIT:int>')<EOL>return curvature_matrix_from_blurred_mapping_matrix_jit(blurred_mapping_matrix, noise_map_1d, flist, iflist)<EOL>

Compute the curvature matrix *F* from a blurred mapping matrix *f* and the 1D noise-map *\sigma* \
     (see Warren & Dye 2003).

    Parameters
    -----------
    blurred_mapping_matrix : ndarray
        The matrix representing the blurred mappings between sub-grid pixels and pixelization pixels.
    noise_map_1d : ndarray
        Flattened 1D array of the noise-map used by the inversion during the fit.


@decorator_util.jit()<EOL>def curvature_matrix_from_blurred_mapping_matrix_jit(blurred_mapping_matrix, noise_map_1d, flist, iflist):

curvature_matrix = np.zeros((blurred_mapping_matrix.shape[<NUM_LIT:1>], blurred_mapping_matrix.shape[<NUM_LIT:1>]))<EOL>for image_index in range(blurred_mapping_matrix.shape[<NUM_LIT:0>]):<EOL><INDENT>index = <NUM_LIT:0><EOL>for pixel_index in range(blurred_mapping_matrix.shape[<NUM_LIT:1>]):<EOL><INDENT>if blurred_mapping_matrix[image_index, pixel_index] > <NUM_LIT:0.0>:<EOL><INDENT>flist[index] = blurred_mapping_matrix[image_index, pixel_index] / noise_map_1d[image_index]<EOL>iflist[index] = pixel_index<EOL>index += <NUM_LIT:1><EOL><DEDENT><DEDENT>if index > <NUM_LIT:0>:<EOL><INDENT>for i1 in range(index):<EOL><INDENT>for j1 in range(index):<EOL><INDENT>ix = iflist[i1]<EOL>iy = iflist[j1]<EOL>curvature_matrix[ix, iy] += flist[i1] * flist[j1]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>for i in range(blurred_mapping_matrix.shape[<NUM_LIT:1>]):<EOL><INDENT>for j in range(blurred_mapping_matrix.shape[<NUM_LIT:1>]):<EOL><INDENT>curvature_matrix[i, j] = curvature_matrix[j, i]<EOL><DEDENT><DEDENT>return curvature_matrix<EOL>

Compute the curvature matrix *F* from a blurred mapping matrix *f* and the 1D noise-map *\sigma* \
    (see Warren & Dye 2003).

    Parameters
    -----------
    blurred_mapping_matrix : ndarray
        The matrix representing the blurred mappings between sub-grid pixels and pixelization pixels.
    noise_map_1d : ndarray
        Flattened 1D array of the noise-map used by the inversion during the fit.
    flist : ndarray
        NumPy array of floats used to store mappings for efficienctly calculation.
    iflist : ndarray
        NumPy array of integers used to store mappings for efficienctly calculation.


reconstructed_data_vector = np.zeros(blurred_mapping_matrix.shape[<NUM_LIT:0>])<EOL>for i in range(blurred_mapping_matrix.shape[<NUM_LIT:0>]):<EOL><INDENT>for j in range(solution_vector.shape[<NUM_LIT:0>]):<EOL><INDENT>reconstructed_data_vector[i] += solution_vector[j] * blurred_mapping_matrix[i, j]<EOL><DEDENT><DEDENT>return reconstructed_data_vector<EOL>

Compute the reconstructed hyper vector from the blurrred mapping matrix *f* and solution vector *S*.

    Parameters
    -----------
    blurred_mapping_matrix : ndarray
        The matrix representing the blurred mappings between sub-grid pixels and pixelization pixels.


self.coefficients = coefficients<EOL>

Abstract base class for a regularization-scheme, which is applied to a pixelization to enforce a \
        smooth-source solution and prevent over-fitting noise_map in the hyper. This is achieved by computing a \
        'regularization term' - which is the sum of differences in reconstructed flux between every set of neighboring \
        pixels. This regularization term is added to the solution's chi-squared as a penalty term. This effects \
        a pixelization in the following ways:

        1) The regularization matrix (see below) is added to the curvature matrix used by the inversion to \
           linearly invert and fit the hyper. Thus, it changes the pixelization in a linear manner, ensuring that \
           the minimum chi-squared solution is achieved accounting for the penalty term.

        2) The likelihood of the pixelization's fit to the hyper changes from L = -0.5 *(chi^2 + noise_normalization) \
           to L = -0.5 (chi^2 + coefficients * regularization_term + noise_normalization). The regularization \
           coefficient is a 'hyper-parameter' which determines how strongly we smooth the pixelization's reconstruction.

        The value of the coefficients(s) is set using the Bayesian framework of (Suyu 2006) and this \
        is described further in the (*inversion.Inversion* class).

        The regularization matrix, H, is calculated by defining a set of B matrices which describe how the \
        pixels neighbor one another. For example, lets take a 3x3 square grid:
        ______
        |0|1|2|
        |3|4|5|
        |6|7|8|
        ^^^^^^^

        We want to regularize this grid such that each pixel is regularized with the pixel to its right and below it \
        (provided there are pixels in that direction). This means that:

        - pixel 0 is regularized with pixel 1 (to the right) and pixel 3 (below).
        - pixel 1 is regularized with pixel 2 (to the right) and pixel 4 (below),
        - Pixel 2 is only regularized with pixel 5, as there is no pixel to its right.
        - and so on.

        We make two 9 x 9 B matrices, which describe regularization in each direction (i.e. rightwards and downwards). \
        We simply put a -1 and 1 in each row of a pixel index where it has a neighbor, where the value 1 goes in the \
        column of its neighbor's index. Thus, the B matrix describing neighboring pixels to their right looks like:

        B_x = [-1,  1,  0,  0,  0,  0,  0,  0,  0] # [0->1]
              [ 0, -1,  1,  0,  0,  0,  0,  0,  0] # [1->2]
              [ 0,  0, -1,  0,  0,  0,  0,  0,  0] # [] NOTE - no pixel neighbor.
              [ 0,  0,  0, -1,  1,  0,  0,  0,  0] # [3->4]
              [ 0,  0,  0,  0, -1,  1,  0,  0,  0] # [4->5]
              [ 0,  0,  0,  0,  0, -1,  0,  0,  0] # [] NOTE - no pixel neighbor.
              [ 0,  0,  0,  0,  0,  0, -1,  1,  0] # [6->7]
              [ 0,  0,  0,  0,  0,  0,  0, -1,  1] # [7->8]
              [ 0,  0,  0,  0,  0,  0,  0,  0, -1] # [] NOTE - no pixel neighbor.

        We now make another B matrix for the regularization downwards:

        B_y = [-1,  0,  0,  1,  0,  0,  0,  0,  0] # [0->3]
              [ 0, -1,  0,  0,  1,  0,  0,  0,  0] # [1->4]
              [ 0,  0, -1,  0,  0,  1,  0,  0,  0] # [2->5]
              [ 0,  0,  0, -1,  0,  0,  1,  0,  0] # [3->6]
              [ 0,  0,  0,  0, -1,  0,  0,  1,  0] # [4->7]
              [ 0,  0,  0,  0,  0, -1,  0,  0,  1] # [5->8]
              [ 0,  0,  0,  0,  0,  0, -1,  0,  0] # [] NOTE - no pixel neighbor.
              [ 0,  0,  0,  0,  0,  0,  0, -1,  0] # [] NOTE - no pixel neighbor.
              [ 0,  0,  0,  0,  0,  0,  0,  0, -1] # [] NOTE - no pixel neighbor.

        After making the B matrices that represent our pixel neighbors, we can compute the regularization matrix, H, \
        of each direction as H = B * B.T (matrix multiplication).

        E.g.

        H_x = B_x.T, * B_x
        H_y = B_y.T * B_y
        H = H_x + H_y

        Whilst the example above used a square-grid with regularization to the right and downwards, this matrix \
        formalism can be extended to describe regularization in more directions (e.g. upwards, to the left).

        It can also describe irregular pixelizations, e.g. an irregular Voronoi pixelization, where a B matrix is \
        computed for every shared Voronoi vertex of each Voronoi pixel. The number of B matrices is now equal to the \
        number of Voronoi vertices in the pixel with the most Voronoi vertices. However, we describe below a scheme to \
        compute this solution more efficiently.

        ### COMBINING B MATRICES ###

        The B matrices above each had the -1's going down the diagonal. This is not necessary, and it is valid to put \
        each pixel pairing anywhere. So, if we had a 4x4 B matrix, where:

        - pixel 0 regularizes with pixel 1
        - pixel 2 regularizes with pixel 3
        - pixel 3 regularizes with pixel 0

        We can still set this up as one matrix (even though the pixel 0 comes up twice):

        B = [-1, 1,  0 , 0] # [0->1]
            [ 0, 0,  0 , 0] # We can skip rows by making them all zeros.
            [ 0, 0, -1 , 1] # [2->3]
            [ 1, 0,  0 ,-1] # [3->0] This is valid!

        So, for a Voronoi pixelzation, we don't have to make the same number of B matrices as Voronoi vertices,  \
        we can combine them into fewer B matrices as above.

        # SKIPPING THE B MATRIX CALCULATION #

        Infact, going through the rigmarole of computing and multiplying B matrices like this is uncessary. It is \
        more computationally efficiently to directly compute H. This is possible, provided you know know all of the \
        neighboring pixel pairs (which, by definition, you need to know to set up the B matrices anyway). Thus, the \
       'regularization_matrix_from_pixel_neighbors' functions in this module directly compute H from the pixel \
        neighbors.

        # POSITIVE DEFINITE MATRIX #

        The regularization matrix must be positive-definite, as the Bayesian framework of Suyu 2006 requires that we \
        use its determinant in the calculation.

        Parameters
        -----------
        shape : (int, int)
            The dimensions of the rectangular grid of pixels (x_pixels, y_pixel)
        coefficients : (float,)
            The regularization_matrix coefficients used to smooth the pix reconstructed_inversion_image.


super(Constant, self).__init__(coefficients)<EOL>

A constant-regularization scheme (regularization is described in the *Regularization* class above).

        For the constant regularization_matrix scheme, there is only 1 regularization coefficient that is applied to \
        all neighboring pixels. This means that we when write B, we only need to regularize pixels in one direction \
        (e.g. pixel 0 regularizes pixel 1, but NOT visa versa). For example:

        B = [-1, 1]  [0->1]
            [0, -1]  1 does not regularization with 0

        A small numerical value of 1.0e-8 is added to all elements in a constant regularization matrix, to ensure that \
        it is positive definite.

        Parameters
        -----------
        coefficients : (float,)
            The regularization coefficient which controls the degree of smooth of the inversion reconstruction.


def __init__(self, coefficients=(<NUM_LIT:1.0>, <NUM_LIT:1.0>), signal_scale=<NUM_LIT:1.0>):

super(Weighted, self).__init__(coefficients)<EOL>self.signal_scale = signal_scale<EOL>

A constant-regularization scheme (regularization is described in the *Regularization* class above).

        For the weighted regularization scheme, each pixel is given an 'effective regularization weight', which is \
        applied when each set of pixel neighbors are regularized with one another. The motivation of this is that \
        different regions of a pixelization require different levels of regularization (e.g., high smoothing where the \
        no signal is present and less smoothing where it is, see (Nightingale, Dye and Massey 2018)).

        Unlike the constant regularization_matrix scheme, neighboring pixels must now be regularized with one another \
        in both directions (e.g. if pixel 0 regularizes pixel 1, pixel 1 must also regularize pixel 0). For example:

        B = [-1, 1]  [0->1]
            [-1, -1]  1 now also regularizes 0

        For a constant regularization coefficient this would NOT produce a positive-definite matrix. However, for
        the weighted scheme, it does!

        The regularize weights change the B matrix as shown below - we simply multiply each pixel's effective \
        regularization weight by each row of B it has a -1 in, so:

        regularization_weights = [1, 2, 3, 4]

        B = [-1, 1, 0 ,0] # [0->1]
            [0, -2, 2 ,0] # [1->2]
            [0, 0, -3 ,3] # [2->3]
            [4, 0, 0 ,-4] # [3->0]

        If our -1's werent down the diagonal this would look like:

        B = [4, 0, 0 ,-4] # [3->0]
            [0, -2, 2 ,0] # [1->2]
            [-1, 1, 0 ,0] # [0->1]
            [0, 0, -3 ,3] # [2->3] This is valid!

        Parameters
        -----------
        coefficients : (float, float)
            The regularization coefficients which controls the degree of smoothing of the inversion reconstruction in \
            high and low signal regions of the reconstruction.
        signal_scale : float
            A factor which controls how rapidly the smoothness of regularization varies from high signal regions to \
            low signal regions.


super(ConvolverMappingMatrix, self).__init__(mask, psf)<EOL>

Class to create number array and frames used to convolve a psf with a 1D vector of non-masked values.

Parameters
----------
mask : Mask
    An datas_ masks, where True eliminates datas.
psf : datas_.PSF or ndarray
    An array representing a PSF.


return self.convolve_matrix_jit(mapping_matrix, self.image_frame_indexes,<EOL>self.image_frame_psfs, self.image_frame_lengths)<EOL>

For a given inversion mapping matrix, convolve every pixel's mapped regular with the PSF kernel.

        A mapping matrix provides non-zero entries in all elements which map two pixels to one another
        (see *inversions.mappers*).

        For example, lets take an regular which is masked using a 'cross' of 5 pixels:

        [[ True, False,  True]],
        [[False, False, False]],
        [[ True, False,  True]]

        As example mapping matrix of this cross is as follows (5 regular pixels x 3 source pixels):

        [1, 0, 0] [0->0]
        [1, 0, 0] [1->0]
        [0, 1, 0] [2->1]
        [0, 1, 0] [3->1]
        [0, 0, 1] [4->2]

        For each source-pixel, we can create an regular of its unit-surface brightnesses by mapping the non-zero
        entries back to masks. For example, doing this for source pixel 1 gives:

        [[0.0, 1.0, 0.0]],
        [[1.0, 0.0, 0.0]]
        [[0.0, 0.0, 0.0]]

        And source pixel 2:

        [[0.0, 0.0, 0.0]],
        [[0.0, 1.0, 1.0]]
        [[0.0, 0.0, 0.0]]

        We then convolve each of these regular with our PSF kernel, in 2 dimensions, like we would a normal regular. For
        example, using the kernel below:

        kernel:

        [[0.0, 0.1, 0.0]]
        [[0.1, 0.6, 0.1]]
        [[0.0, 0.1, 0.0]]

        Blurred Source Pixel 1 (we don't need to perform the convolution into masked pixels):

        [[0.0, 0.6, 0.0]],
        [[0.6, 0.0, 0.0]],
        [[0.0, 0.0, 0.0]]

        Blurred Source pixel 2:

        [[0.0, 0.0, 0.0]],
        [[0.0, 0.7, 0.7]],
        [[0.0, 0.0, 0.0]]

        Finally, we map each of these blurred regular back to a blurred mapping matrix, which is analogous to the
        mapping matrix.

        [0.6, 0.0, 0.0] [0->0]
        [0.6, 0.0, 0.0] [1->0]
        [0.0, 0.7, 0.0] [2->1]
        [0.0, 0.7, 0.0] [3->1]
        [0.0, 0.0, 0.6] [4->2]

        If the mapping matrix is sub-gridded, we perform the convolution on the fractional surface brightnesses in an
        identical fashion to above.

        Parameters
        -----------
        mapping_matrix : ndarray
            The 2D mapping matix describing how every inversion pixel maps to an datas_ pixel.


if vor.points.shape[<NUM_LIT:1>] != <NUM_LIT:2>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>new_regions = []<EOL>new_vertices = vor.vertices.tolist()<EOL>center = vor.points.mean(axis=<NUM_LIT:0>)<EOL>if radius is None:<EOL><INDENT>radius = vor.points.ptp().max()*<NUM_LIT:2><EOL><DEDENT>all_ridges = {}<EOL>for (p1, p2), (v1, v2) in zip(vor.ridge_points, vor.ridge_vertices):<EOL><INDENT>all_ridges.setdefault(p1, []).append((p2, v1, v2))<EOL>all_ridges.setdefault(p2, []).append((p1, v1, v2))<EOL><DEDENT>for p1, region in enumerate(vor.point_region):<EOL><INDENT>vertices = vor.regions[region]<EOL>if all(v >= <NUM_LIT:0> for v in vertices):<EOL><INDENT>new_regions.append(vertices)<EOL>continue<EOL><DEDENT>ridges = all_ridges[p1]<EOL>new_region = [v for v in vertices if v >= <NUM_LIT:0>]<EOL>for p2, v1, v2 in ridges:<EOL><INDENT>if v2 < <NUM_LIT:0>:<EOL><INDENT>v1, v2 = v2, v1<EOL><DEDENT>if v1 >= <NUM_LIT:0>:<EOL><INDENT>continue<EOL><DEDENT>t = vor.points[p2] - vor.points[p1] <EOL>t /= np.linalg.norm(t)<EOL>n = np.array([-t[<NUM_LIT:1>], t[<NUM_LIT:0>]])  <EOL>midpoint = vor.points[[p1, p2]].mean(axis=<NUM_LIT:0>)<EOL>direction = np.sign(np.dot(midpoint - center, n)) * n<EOL>far_point = vor.vertices[v2] + direction * radius<EOL>new_region.append(len(new_vertices))<EOL>new_vertices.append(far_point.tolist())<EOL><DEDENT>vs = np.asarray([new_vertices[v] for v in new_region])<EOL>c = vs.mean(axis=<NUM_LIT:0>)<EOL>angles = np.arctan2(vs[:,<NUM_LIT:1>] - c[<NUM_LIT:1>], vs[:,<NUM_LIT:0>] - c[<NUM_LIT:0>])<EOL>new_region = np.array(new_region)[np.argsort(angles)]<EOL>new_regions.append(new_region.tolist())<EOL><DEDENT>return new_regions, np.asarray(new_vertices)<EOL>

Reconstruct infinite voronoi regions in a 2D diagram to finite
regions.
Parameters
----------
vor : Voronoi
    Input diagram
radius : float, optional
    Distance to 'points at infinity'.
Returns
-------
regions : list of tuples
    Indices of vertices in each revised Voronoi regions.
vertices : list of tuples
    Coordinates for revised Voronoi vertices. Same as coordinates
    of input vertices, with 'points at infinity' appended to the
    end.


def __init__(self, pixels, grid_stack, border):

self.pixels = pixels<EOL>self.grid_stack = grid_stack<EOL>self.border = border<EOL>

Abstract base class representing a mapper, which maps unmasked pixels on a masked 2D array (in the form of \
        a grid, see the *hyper.array.grid_stack* module) to discretized pixels in a pixelization.

        1D arrays are used to represent these mappings, for example between the different grid_stack in a grid-stack \
        (e.g. the regular / sub grid_stack). This follows the syntax grid_to_grid, whereby the index of a value on one grid \
        equals that of another grid, for example:

        - image_to_pix[2] = 1  tells us that the 3rd pixel on a regular grid maps to the 2nd pixel of a pixelization.
        - sub_to_pix4] = 2  tells us that the 5th sub-pixel of a sub-grid maps to the 3rd pixel of a pixelization.
        - pix_to_image[2] = 5 tells us that the 3rd pixel of a pixelization maps to the 6th (unmasked) pixel of a \
                            regular grid.

        Parameters
        ----------
        pixels : int
            The number of pixels in the mapper's pixelization.
        grid_stack: grid_stack.GridStack
            A stack of grid's which are mapped to the pixelization (includes an regular and sub grid).
        border : grid_stack.RegularGridBorder
            The border of the grid-stack's regular-grid.


The mapping matrix is a matrix representing the mapping between every unmasked pixel of a grid and \
        the pixels of a pixelization. Non-zero entries signify a mapping, whereas zeros signify no mapping.

        For example, if the regular grid has 5 pixels and the pixelization 3 pixels, with the following mappings:

        regular pixel 0 -> pixelization pixel 0
        regular pixel 1 -> pixelization pixel 0
        regular pixel 2 -> pixelization pixel 1
        regular pixel 3 -> pixelization pixel 1
        regular pixel 4 -> pixelization pixel 2

        The mapping matrix (which is of dimensions regular_pixels x pixelization_pixels) would appear as follows:

        [1, 0, 0] [0->0]
        [1, 0, 0] [1->0]
        [0, 1, 0] [2->1]
        [0, 1, 0] [3->1]
        [0, 0, 1] [4->2]

        The mapping matrix is in fact built using the sub-grid of the grid-stack, whereby each regular-pixel is \
        divided into a regular grid of sub-pixels which are all paired to pixels in the pixelization. The entires \
        in the mapping matrix now become fractional values dependent on the sub-grid size. For example, for a 2x2 \
        sub-grid in each pixel (which means the fraction value is 1.0/(2.0^2) = 0.25, if we have the following mappings:

        regular pixel 0 -> sub pixel 0 -> pixelization pixel 0
        regular pixel 0 -> sub pixel 1 -> pixelization pixel 1
        regular pixel 0 -> sub pixel 2 -> pixelization pixel 1
        regular pixel 0 -> sub pixel 3 -> pixelization pixel 1
        regular pixel 1 -> sub pixel 0 -> pixelization pixel 1
        regular pixel 1 -> sub pixel 1 -> pixelization pixel 1
        regular pixel 1 -> sub pixel 2 -> pixelization pixel 1
        regular pixel 1 -> sub pixel 3 -> pixelization pixel 1
        regular pixel 2 -> sub pixel 0 -> pixelization pixel 2
        regular pixel 2 -> sub pixel 1 -> pixelization pixel 2
        regular pixel 2 -> sub pixel 2 -> pixelization pixel 3
        regular pixel 2 -> sub pixel 3 -> pixelization pixel 3

        The mapping matrix (which is still of dimensions regular_pixels x source_pixels) would appear as follows:

        [0.25, 0.75, 0.0, 0.0] [1 sub-pixel maps to pixel 0, 3 map to pixel 1]
        [ 0.0,  1.0, 0.0, 0.0] [All sub-pixels map to pixel 1]
        [ 0.0,  0.0, 0.5, 0.5] [2 sub-pixels map to pixel 2, 2 map to pixel 3]


pix_to_regular = [[] for _ in range(self.pixels)]<EOL>for regular_pixel, pix_pixel in enumerate(self.regular_to_pix):<EOL><INDENT>pix_to_regular[pix_pixel].append(regular_pixel)<EOL><DEDENT>return pix_to_regular<EOL>

Compute the mappings between a pixelization's pixels and the unmasked regular-grid pixels. These mappings \
        are determined after the regular-grid is used to determine the pixelization.

        The pixelization's pixels map to different number of regular-grid pixels, thus a list of lists is used to \
        represent these mappings


pix_to_sub = [[] for _ in range(self.pixels)]<EOL>for regular_pixel, pix_pixel in enumerate(self.sub_to_pix):<EOL><INDENT>pix_to_sub[pix_pixel].append(regular_pixel)<EOL><DEDENT>return pix_to_sub<EOL>

Compute the mappings between a pixelization's pixels and the unmasked sub-grid pixels. These mappings \
        are determined after the regular-grid is used to determine the pixelization.

        The pixelization's pixels map to different number of sub-grid pixels, thus a list of lists is used to \
        represent these mappings


def __init__(self, pixels, grid_stack, border, shape, geometry):

self.shape = shape<EOL>self.geometry = geometry<EOL>super(RectangularMapper, self).__init__(pixels, grid_stack, border)<EOL>

Class representing a rectangular mapper, which maps unmasked pixels on a masked 2D array (in the form of \
        a grid, see the *hyper.array.grid_stack* module) to pixels discretized on a rectangular grid.

        The regular and uniform geometry of the rectangular grid is used to perform efficient pixel pairings.

        Parameters
        ----------
        pixels : int
            The number of pixels in the rectangular pixelization (y_pixels*x_pixels).
        grid_stack : grid_stack.GridStack
            A stack of grid describing the observed image's pixel coordinates (e.g. an image-grid, sub-grid, etc.).
        border : grid_stack.RegularGridBorder
            The border of the grid-stack's regular-grid.
        shape : (int, int)
            The dimensions of the rectangular grid of pixels (y_pixels, x_pixel)
        geometry : pixelization.Rectangular.Geometry
            The geometry (e.g. y / x edge locations, pixel-scales) of the rectangular pixelization.


return self.geometry.grid_arcsec_to_grid_pixel_indexes(grid_arcsec=self.grid_stack.regular)<EOL>

The 1D index mappings between the regular grid's pixels and rectangular pixelization's pixels.


return self.geometry.grid_arcsec_to_grid_pixel_indexes(grid_arcsec=self.grid_stack.sub)<EOL>

The 1D index mappings between the sub grid's pixels and rectangular pixelization's pixels


Given the solution vector of an inversion (see *inversions.Inversion*), determine the reconstructed \
        pixelization of the rectangular pixelization by using the mapper.


def __init__(self, pixels, grid_stack, border, voronoi, geometry):

self.voronoi = voronoi<EOL>self.geometry = geometry<EOL>super(VoronoiMapper, self).__init__(pixels, grid_stack, border)<EOL>

Class representing a Voronoi mapper, which maps unmasked pixels on a masked 2D array (in the form of \
        a grid, see the *hyper.array.grid_stack* module) to pixels discretized on a Voronoi grid.

        The irregular and non-uniform geometry of the Voronoi grid means efficient pixel pairings requires knowledge \
        of how different grid_stack map to one another.

        Parameters
        ----------
        pixels : int
            The number of pixels in the Voronoi pixelization.
        grid_stack : grid_stack.GridStack
            A stack of grid describing the observed image's pixel coordinates (e.g. an image-grid, sub-grid, etc.).
        border : grid_stack.RegularGridBorder
            The border of the grid-stack's regular-grid.
        voronoi : scipy.spatial.Voronoi
            Class storing the Voronoi grid's geometry.
        geometry : pixelization.Voronoi.Geometry
            The geometry (e.g. y / x edge locations, pixel-scales) of the Vornoi pixelization.


The 1D index mappings between the regular pixels and Voronoi pixelization pixels.


The 1D index mappings between the sub pixels and Voronoi pixelization pixels.


def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>sersic_index: float = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>):

EllipticalSersic.__init__(self, centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>,<EOL>intensity=intensity, effective_radius=effective_radius, sersic_index=sersic_index,<EOL>mass_to_light_ratio=mass_to_light_ratio)<EOL>

The SphericalSersic mass profile, the mass profiles of the light profiles that are used to fit_normal and
subtract the lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The regular_grid of the origin of the profiles
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The radius containing half the light of this model_mapper
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles


def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>):

EllipticalSersic.__init__(self, centre=centre, axis_ratio=axis_ratio, phi=phi,<EOL>intensity=intensity, effective_radius=effective_radius,<EOL>sersic_index=<NUM_LIT:1.0>, mass_to_light_ratio=mass_to_light_ratio)<EOL>

The EllipticalExponential mass profile, the mass profiles of the light profiles that are used to fit_normal and
subtract the lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The regular_grid of the origin of the profiles
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a)
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The radius containing half the light of this model_mapper
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles


def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>):

EllipticalExponential.__init__(self, centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, intensity=intensity,<EOL>effective_radius=effective_radius, mass_to_light_ratio=mass_to_light_ratio)<EOL>

The SphericalExponential mass profile, the mass profiles of the light profiles that are used to fit_normal and
subtract the lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The regular_grid of the origin of the profiles
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The radius containing half the light of this model_mapper
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles


super(EllipticalDevVaucouleurs, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi,<EOL>intensity=intensity, effective_radius=effective_radius,<EOL>sersic_index=<NUM_LIT>, mass_to_light_ratio=mass_to_light_ratio)<EOL>

The EllipticalDevVaucouleurs mass profile, the mass profiles of the light profiles that are used to fit_normal and
subtract the lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The regular_grid of the origin of the profiles
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a)
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The radius containing half the light of this model_mapper
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles


EllipticalDevVaucouleurs.__init__(self, centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, intensity=intensity,<EOL>effective_radius=effective_radius, mass_to_light_ratio=mass_to_light_ratio)<EOL>

The SphericalDevVaucouleurs mass profile, the mass profiles of the light profiles that are used to fit_normal and
subtract the lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The regular_grid of the origin of the profiles
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The radius containing half the light of this model_mapper
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles


def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>sersic_index: float = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>,<EOL>mass_to_light_gradient: float = <NUM_LIT:0.0>):

Setup a Sersic mass and light profiles.

Parameters
----------
centre: (float, float)
    The origin of the profiles
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a)
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The radius containing half the light of this model_mapper
sersic_index : Int
    The concentration of the light profiles
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles
mass_to_light_gradient : float
    The mass-to-light radial gradient.


def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>sersic_index: float = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>,<EOL>mass_to_light_gradient: float = <NUM_LIT:0.0>):

EllipticalSersicRadialGradient.__init__(self, centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, intensity=intensity,<EOL>effective_radius=effective_radius, sersic_index=sersic_index,<EOL>mass_to_light_ratio=mass_to_light_ratio,<EOL>mass_to_light_gradient=mass_to_light_gradient)<EOL>

Setup a Sersic mass and light profiles.

Parameters
----------
centre: (float, float)
    The origin of the profiles
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The radius containing half the light of this model_mapper
sersic_index : Int
    The concentration of the light profiles
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles
mass_to_light_gradient : float
    The mass-to-light radial gradient.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>):<DEDENT>

super(PointMass, self).__init__(centre=centre)<EOL>self.einstein_radius = einstein_radius<EOL>

Represents a point-mass.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
einstein_radius : float
    The arc-second Einstein radius of the point-mass.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>):<DEDENT>

super(EllipticalMassProfile, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi)<EOL>self.axis_ratio = axis_ratio<EOL>self.phi = phi<EOL>

Abstract class for elliptical mass profiles.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    Ellipse's minor-to-major axis ratio (b/a)
phi : float
    Rotation angle of profile's ellipse counter-clockwise from positive x-axis


def mass_within_circle_in_units(self, radius: dim.Length, unit_mass='<STR_LIT>', kpc_per_arcsec=None,<EOL>critical_surface_density=None):

self.check_units_of_radius_and_critical_surface_density(<EOL>radius=radius, critical_surface_density=critical_surface_density)<EOL>profile = self.new_profile_with_units_converted(<EOL>unit_length=radius.unit_length, unit_mass='<STR_LIT>',<EOL>kpc_per_arcsec=kpc_per_arcsec, critical_surface_density=critical_surface_density)<EOL>mass_angular = dim.Mass(value=quad(profile.mass_integral, a=<NUM_LIT:0.0>, b=radius, args=(<NUM_LIT:1.0>,))[<NUM_LIT:0>], unit_mass='<STR_LIT>')<EOL>return mass_angular.convert(unit_mass=unit_mass, critical_surface_density=critical_surface_density)<EOL>

Integrate the mass profiles's convergence profile to compute the total mass within a circle of \
        specified radius. This is centred on the mass profile.

        The following units for mass can be specified and output:

        - Dimensionless angular units (default) - 'angular'.
        - Solar masses - 'angular' (multiplies the angular mass by the critical surface mass density).

        Parameters
        ----------
        radius : dim.Length
            The radius of the circle to compute the dimensionless mass within.
        unit_mass : str
            The units the mass is returned in (angular | angular).
        critical_surface_density : float or None
            The critical surface mass density of the strong lens configuration, which converts mass from angulalr \
            units to phsical units (e.g. solar masses).


def mass_within_ellipse_in_units(self, major_axis, unit_mass='<STR_LIT>', kpc_per_arcsec=None,<EOL>critical_surface_density=None):

self.check_units_of_radius_and_critical_surface_density(<EOL>radius=major_axis, critical_surface_density=critical_surface_density)<EOL>profile = self.new_profile_with_units_converted(<EOL>unit_length=major_axis.unit_length, unit_mass='<STR_LIT>',<EOL>kpc_per_arcsec=kpc_per_arcsec, critical_surface_density=critical_surface_density)<EOL>mass_angular = dim.Mass(value=quad(profile.mass_integral, a=<NUM_LIT:0.0>, b=major_axis, args=(self.axis_ratio,))[<NUM_LIT:0>],<EOL>unit_mass='<STR_LIT>')<EOL>return mass_angular.convert(unit_mass=unit_mass, critical_surface_density=critical_surface_density)<EOL>

Integrate the mass profiles's convergence profile to compute the total angular mass within an ellipse of \
        specified major axis. This is centred on the mass profile.

        The following units for mass can be specified and output:

        - Dimensionless angular units (default) - 'angular'.
        - Solar masses - 'angular' (multiplies the angular mass by the critical surface mass density)

        Parameters
        ----------
        major_axis : float
            The major-axis radius of the ellipse.
        unit_mass : str
            The units the mass is returned in (angular | angular).
        critical_surface_density : float or None
            The critical surface mass density of the strong lens configuration, which converts mass from angular \
            units to phsical units (e.g. solar masses).


r = x * axis_ratio<EOL>return <NUM_LIT:2> * np.pi * r * self.convergence_func(x)<EOL>

Routine to integrate an elliptical light profiles - set axis ratio to 1 to compute the luminosity within a \
        circle


def density_between_circular_annuli_in_angular_units(self, inner_annuli_radius, outer_annuli_radius):

annuli_area = (np.pi * outer_annuli_radius ** <NUM_LIT>) - (np.pi * inner_annuli_radius ** <NUM_LIT>)<EOL>return (self.mass_within_circle_in_units(radius=outer_annuli_radius) -<EOL>self.mass_within_circle_in_units(radius=inner_annuli_radius))/ annuli_area<EOL>

Calculate the mass between two circular annuli and compute the density by dividing by the annuli surface
        area.

        The value returned by the mass integral is dimensionless, therefore the density between annuli is returned in \
        units of inverse radius squared. A conversion factor can be specified to convert this to a physical value \
        (e.g. the critical surface mass density).

        Parameters
        -----------
        inner_annuli_radius : float
            The radius of the inner annulus outside of which the density are estimated.
        outer_annuli_radius : float
            The radius of the outer annulus inside of which the density is estimated.


def average_convergence_of_1_radius_in_units(self, unit_length='<STR_LIT>', kpc_per_arcsec=None):

def func(radius):<EOL><INDENT>radius = dim.Length(radius, unit_length=unit_length)<EOL>return self.mass_within_circle_in_units(radius=radius) - np.pi * radius ** <NUM_LIT><EOL><DEDENT>radius = self.ellipticity_rescale * root_scalar(func, bracket=[<NUM_LIT>, <NUM_LIT>]).root<EOL>radius = dim.Length(radius, unit_length)<EOL>return radius.convert(unit_length=unit_length, kpc_per_arcsec=kpc_per_arcsec)<EOL>

The radius a critical curve forms for this mass profile, e.g. where the mean convergence is equal to 1.0.

         In case of ellipitical mass profiles, the 'average' critical curve is used, whereby the convergence is \
         rescaled into a circle using the axis ratio.

         This radius corresponds to the Einstein radius of the mass profile, and is a property of a number of \
         mass profiles below.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>,<EOL>slope: float = <NUM_LIT>,<EOL>core_radius: dim.Length = <NUM_LIT>):<DEDENT>

super(EllipticalCoredPowerLaw, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi)<EOL>self.einstein_radius = einstein_radius<EOL>self.slope = slope<EOL>self.core_radius = core_radius<EOL>

Represents a cored elliptical power-law density distribution

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    The elliptical mass profile's minor-to-major axis ratio (b/a).
phi : float
    Rotation angle of mass profile's ellipse counter-clockwise from positive x-axis.
einstein_radius : float
    The arc-second Einstein radius.
slope : float
    The density slope of the power-law (lower value -> shallower profile, higher value -> steeper profile).
core_radius : float
    The arc-second radius of the inner core.


return ((<NUM_LIT:3> - self.slope) / (<NUM_LIT:1> + self.axis_ratio)) * self.einstein_radius ** (self.slope - <NUM_LIT:1>)<EOL>

Rescale the einstein radius by slope and axis_ratio, to reduce its degeneracy with other mass-profiles
        parameters


surface_density_grid = np.zeros(grid.shape[<NUM_LIT:0>])<EOL>grid_eta = self.grid_to_elliptical_radii(grid)<EOL>for i in range(grid.shape[<NUM_LIT:0>]):<EOL><INDENT>surface_density_grid[i] = self.convergence_func(grid_eta[i])<EOL><DEDENT>return surface_density_grid<EOL>

Calculate the projected convergence at a given set of arc-second gridded coordinates.

        Parameters
        ----------
        grid : grids.RegularGrid
            The grid of (y,x) arc-second coordinates the surface density is computed on.


potential_grid = quad_grid(self.potential_func, <NUM_LIT:0.0>, <NUM_LIT:1.0>, grid,<EOL>args=(self.axis_ratio, self.slope, self.core_radius))[<NUM_LIT:0>]<EOL>return self.einstein_radius_rescaled * self.axis_ratio * potential_grid<EOL>

Calculate the potential at a given set of arc-second gridded coordinates.

Parameters
----------
grid : grids.RegularGrid
    The grid of (y,x) arc-second coordinates the deflection angles are computed on.


def calculate_deflection_component(npow, index):<EOL><INDENT>einstein_radius_rescaled = self.einstein_radius_rescaled<EOL>deflection_grid = self.axis_ratio * grid[:, index]<EOL>deflection_grid *= quad_grid(self.deflection_func, <NUM_LIT:0.0>, <NUM_LIT:1.0>,<EOL>grid, args=(npow, self.axis_ratio,<EOL>einstein_radius_rescaled, self.slope,<EOL>self.core_radius))[<NUM_LIT:0>]<EOL>return deflection_grid<EOL><DEDENT>deflection_y = calculate_deflection_component(<NUM_LIT:1.0>, <NUM_LIT:0>)<EOL>deflection_x = calculate_deflection_component(<NUM_LIT:0.0>, <NUM_LIT:1>)<EOL>return self.rotate_grid_from_profile(np.multiply(<NUM_LIT:1.0>, np.vstack((deflection_y, deflection_x)).T))<EOL>

Calculate the deflection angles at a given set of arc-second gridded coordinates.

Parameters
----------
grid : grids.RegularGrid
    The grid of (y,x) arc-second coordinates the deflection angles are computed on.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>,<EOL>slope: float = <NUM_LIT>,<EOL>core_radius: dim.Length = <NUM_LIT>):<DEDENT>

super(SphericalCoredPowerLaw, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>,<EOL>einstein_radius=einstein_radius, slope=slope,<EOL>core_radius=core_radius)<EOL>

Represents a cored spherical power-law density distribution

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
einstein_radius : float
    The arc-second Einstein radius.
slope : float
    The density slope of the power-law (lower value -> shallower profile, higher value -> steeper profile).
core_radius : float
    The arc-second radius of the inner core.


eta = self.grid_to_grid_radii(grid=grid)<EOL>deflection = np.multiply(<NUM_LIT> * self.einstein_radius_rescaled, np.divide(<EOL>np.add(np.power(np.add(self.core_radius ** <NUM_LIT:2>, np.square(eta)), (<NUM_LIT> - self.slope) / <NUM_LIT>),<EOL>-self.core_radius ** (<NUM_LIT:3> - self.slope)), np.multiply((<NUM_LIT> - self.slope), eta)))<EOL>return self.grid_to_grid_cartesian(grid=grid, radius=deflection)<EOL>


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>,<EOL>slope: float = <NUM_LIT>):<DEDENT>

super(EllipticalPowerLaw, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi,<EOL>einstein_radius=einstein_radius, slope=slope,<EOL>core_radius=dim.Length(<NUM_LIT:0.0>))<EOL>

Represents an elliptical power-law density distribution.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    The elliptical mass profile's minor-to-major axis ratio (b/a).
phi : float
    Rotation angle of mass profile's ellipse counter-clockwise from positive x-axis.
einstein_radius : float
    The arc-second Einstein radius.
slope : float
    The density slope of the power-law (lower value -> shallower profile, higher value -> steeper profile).


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>,<EOL>slope: float = <NUM_LIT>):<DEDENT>

super(SphericalPowerLaw, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, einstein_radius=einstein_radius,<EOL>slope=slope)<EOL>

Represents a spherical power-law density distribution.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
einstein_radius : float
    The arc-second Einstein radius.
slope : float
    The density slope of the power-law (lower value -> shallower profile, higher value -> steeper profile).


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>,<EOL>core_radius: dim.Length = <NUM_LIT>):<DEDENT>

super(EllipticalCoredIsothermal, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi,<EOL>einstein_radius=einstein_radius, slope=<NUM_LIT>,<EOL>core_radius=core_radius)<EOL>

Represents a cored elliptical isothermal density distribution, which is equivalent to the elliptical power-law
density distribution for the value slope: float = 2.0

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    The elliptical mass profile's minor-to-major axis ratio (b/a).
phi : float
    Rotation angle of mass profile's ellipse counter-clockwise from positive x-axis.
einstein_radius : float
    The arc-second Einstein radius.
core_radius : float
    The arc-second radius of the inner core.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>,<EOL>core_radius: dim.Length = <NUM_LIT>):<DEDENT>

super(SphericalCoredIsothermal, self).__init__(centre=centre, einstein_radius=einstein_radius, slope=<NUM_LIT>,<EOL>core_radius=core_radius)<EOL>

Represents a cored spherical isothermal density distribution, which is equivalent to the elliptical power-law
density distribution for the value slope: float = 2.0

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
einstein_radius : float
    The arc-second Einstein radius.
core_radius : float
    The arc-second radius of the inner core.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>einstein_radius: dim.Length = <NUM_LIT:1.0>):<DEDENT>

super(EllipticalIsothermal, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi,<EOL>einstein_radius=einstein_radius, slope=<NUM_LIT>)<EOL>

Represents an elliptical isothermal density distribution, which is equivalent to the elliptical power-law
density distribution for the value slope: float = 2.0

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    The elliptical mass profile's minor-to-major axis ratio (b/a).
phi : float
    Rotation angle of mass profile's ellipse counter-clockwise from positive x-axis.
einstein_radius : float
    The arc-second Einstein radius.


factor = <NUM_LIT> * self.einstein_radius_rescaled * self.axis_ratio / np.sqrt(<NUM_LIT:1> - self.axis_ratio ** <NUM_LIT:2>)<EOL>psi = np.sqrt(np.add(np.multiply(self.axis_ratio ** <NUM_LIT:2>, np.square(grid[:, <NUM_LIT:1>])), np.square(grid[:, <NUM_LIT:0>])))<EOL>deflection_y = np.arctanh(np.divide(np.multiply(np.sqrt(<NUM_LIT:1> - self.axis_ratio ** <NUM_LIT:2>), grid[:, <NUM_LIT:0>]), psi))<EOL>deflection_x = np.arctan(np.divide(np.multiply(np.sqrt(<NUM_LIT:1> - self.axis_ratio ** <NUM_LIT:2>), grid[:, <NUM_LIT:1>]), psi))<EOL>return self.rotate_grid_from_profile(np.multiply(factor, np.vstack((deflection_y, deflection_x)).T))<EOL>

Calculate the deflection angles at a given set of arc-second gridded coordinates.

For coordinates (0.0, 0.0) the analytic calculation of the deflection angle gives a NaN. Therefore, \
coordinates at (0.0, 0.0) are shifted slightly to (1.0e-8, 1.0e-8).

Parameters
----------
grid : grids.RegularGrid
    The grid of (y,x) arc-second coordinates the deflection angles are computed on.


super(SphericalIsothermal, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>,<EOL>einstein_radius=einstein_radius)<EOL>

Represents a spherical isothermal density distribution, which is equivalent to the spherical power-law
density distribution for the value slope: float = 2.0

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
einstein_radius : float
    The arc-second Einstein radius.


eta = self.grid_to_elliptical_radii(grid)<EOL>return <NUM_LIT> * self.einstein_radius_rescaled * eta<EOL>


return self.grid_to_grid_cartesian(grid=grid,<EOL>radius=np.full(grid.shape[<NUM_LIT:0>], <NUM_LIT> * self.einstein_radius_rescaled))<EOL>


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>kappa_s: float = <NUM_LIT>,<EOL>inner_slope: float = <NUM_LIT:1.0>,<EOL>scale_radius: dim.Length = <NUM_LIT:1.0>):<DEDENT>

super(AbstractEllipticalGeneralizedNFW, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi)<EOL>super(MassProfile, self).__init__()<EOL>self.kappa_s = kappa_s<EOL>self.scale_radius = scale_radius<EOL>self.inner_slope = inner_slope<EOL>

The elliptical NFW profiles, used to fit the dark matter halo of the lens.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a).
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis.
kappa_s : float
    The overall normalization of the dark matter halo \
    (kappa_s = (rho_s * scale_radius)/lensing_critical_density)
inner_slope : float
    The inner slope of the dark matter halo
scale_radius : float
    The arc-second radius where the average density within this radius is 200 times the critical density of \
    the Universe..


def tabulate_integral(self, grid, tabulate_bins):

eta_min = <NUM_LIT><EOL>eta_max = <NUM_LIT> * np.max(self.grid_to_elliptical_radii(grid))<EOL>minimum_log_eta = np.log10(eta_min)<EOL>maximum_log_eta = np.log10(eta_max)<EOL>bin_size = (maximum_log_eta - minimum_log_eta) / (tabulate_bins - <NUM_LIT:1>)<EOL>return eta_min, eta_max, minimum_log_eta, maximum_log_eta, bin_size<EOL>

Tabulate an integral over the surface density of deflection potential of a mass profile. This is used in \
        the GeneralizedNFW profile classes to speed up the integration procedure.

        Parameters
        -----------
        grid : grids.RegularGrid
            The grid of (y,x) arc-second coordinates the potential / deflection_stacks are computed on.
        tabulate_bins : int
            The number of bins to tabulate the inner integral of this profile.


surface_density_grid = np.zeros(shape=grid.shape[<NUM_LIT:0>])<EOL>grid_eta = self.grid_to_elliptical_radii(grid)<EOL>for i in range(grid.shape[<NUM_LIT:0>]):<EOL><INDENT>surface_density_grid[i] = self.convergence_func(grid_eta[i])<EOL><DEDENT>return surface_density_grid<EOL>


@jit_integrand<EOL>def deflection_integrand(x, kappa_radius, scale_radius, inner_slope):<EOL><INDENT>return (x + kappa_radius / scale_radius) ** (inner_slope - <NUM_LIT:3>) * ((<NUM_LIT:1> - np.sqrt(<NUM_LIT:1> - x ** <NUM_LIT:2>)) / x)<EOL><DEDENT>eta_min, eta_max, minimum_log_eta, maximum_log_eta, bin_size = self.tabulate_integral(grid, tabulate_bins)<EOL>potential_grid = np.zeros(grid.shape[<NUM_LIT:0>])<EOL>deflection_integral = np.zeros((tabulate_bins,))<EOL>for i in range(tabulate_bins):<EOL><INDENT>eta = <NUM_LIT> ** (minimum_log_eta + (i - <NUM_LIT:1>) * bin_size)<EOL>integral =quad(deflection_integrand, a=<NUM_LIT:0.0>, b=<NUM_LIT:1.0>, args=(eta, self.scale_radius, self.inner_slope),<EOL>epsrel=EllipticalGeneralizedNFW.epsrel)[<NUM_LIT:0>]<EOL>deflection_integral[i] = ((eta / self.scale_radius) ** (<NUM_LIT:2> - self.inner_slope)) * (<EOL>(<NUM_LIT:1.0> / (<NUM_LIT:3> - self.inner_slope)) *<EOL>special.hyp2f1(<NUM_LIT:3> - self.inner_slope, <NUM_LIT:3> - self.inner_slope, <NUM_LIT:4> - self.inner_slope,<EOL>- (eta / self.scale_radius)) + integral)<EOL><DEDENT>for i in range(grid.shape[<NUM_LIT:0>]):<EOL><INDENT>potential_grid[i] = (<NUM_LIT> * self.kappa_s * self.axis_ratio) *quad(self.potential_func, a=<NUM_LIT:0.0>, b=<NUM_LIT:1.0>, args=(grid[i, <NUM_LIT:0>], grid[i, <NUM_LIT:1>],<EOL>self.axis_ratio, minimum_log_eta,<EOL>maximum_log_eta, tabulate_bins,<EOL>deflection_integral),<EOL>epsrel=EllipticalGeneralizedNFW.epsrel)[<NUM_LIT:0>]<EOL><DEDENT>return potential_grid<EOL>

Calculate the potential at a given set of arc-second gridded coordinates.

Parameters
----------
grid : grids.RegularGrid
    The grid of (y,x) arc-second coordinates the deflection angles are computed on.
tabulate_bins : int
    The number of bins to tabulate the inner integral of this profile.


@jit_integrand<EOL>def surface_density_integrand(x, kappa_radius, scale_radius, inner_slope):<EOL><INDENT>return (<NUM_LIT:3> - inner_slope) * (x + kappa_radius / scale_radius) ** (inner_slope - <NUM_LIT:4>) * (<NUM_LIT:1> - np.sqrt(<NUM_LIT:1> - x * x))<EOL><DEDENT>def calculate_deflection_component(npow, index):<EOL><INDENT>deflection_grid = <NUM_LIT> * self.kappa_s * self.axis_ratio * grid[:, index]<EOL>deflection_grid *= quad_grid(self.deflection_func, <NUM_LIT:0.0>, <NUM_LIT:1.0>,<EOL>grid, args=(npow, self.axis_ratio, minimum_log_eta, maximum_log_eta,<EOL>tabulate_bins, surface_density_integral),<EOL>epsrel=EllipticalGeneralizedNFW.epsrel)[<NUM_LIT:0>]<EOL>return deflection_grid<EOL><DEDENT>eta_min, eta_max, minimum_log_eta, maximum_log_eta, bin_size = self.tabulate_integral(grid, tabulate_bins)<EOL>surface_density_integral = np.zeros((tabulate_bins,))<EOL>for i in range(tabulate_bins):<EOL><INDENT>eta = <NUM_LIT> ** (minimum_log_eta + (i - <NUM_LIT:1>) * bin_size)<EOL>integral = quad(surface_density_integrand, a=<NUM_LIT:0.0>, b=<NUM_LIT:1.0>, args=(eta, self.scale_radius,<EOL>self.inner_slope),<EOL>epsrel=EllipticalGeneralizedNFW.epsrel)[<NUM_LIT:0>]<EOL>surface_density_integral[i] = ((eta / self.scale_radius) ** (<NUM_LIT:1> - self.inner_slope)) *(((<NUM_LIT:1> + eta / self.scale_radius) ** (self.inner_slope - <NUM_LIT:3>)) + integral)<EOL><DEDENT>deflection_y = calculate_deflection_component(<NUM_LIT:1.0>, <NUM_LIT:0>)<EOL>deflection_x = calculate_deflection_component(<NUM_LIT:0.0>, <NUM_LIT:1>)<EOL>return self.rotate_grid_from_profile(np.multiply(<NUM_LIT:1.0>, np.vstack((deflection_y, deflection_x)).T))<EOL>

Calculate the deflection angles at a given set of arc-second gridded coordinates.

Parameters
----------
grid : grids.RegularGrid
    The grid of (y,x) arc-second coordinates the deflection angles are computed on.
tabulate_bins : int
    The number of bins to tabulate the inner integral of this profile.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>kappa_s: float = <NUM_LIT>,<EOL>inner_slope: float = <NUM_LIT:1.0>,<EOL>scale_radius: dim.Length = <NUM_LIT:1.0>):<DEDENT>

super(SphericalGeneralizedNFW, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, kappa_s=kappa_s,<EOL>inner_slope=inner_slope, scale_radius=scale_radius)<EOL>

The spherical NFW profiles, used to fit the dark matter halo of the lens.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
kappa_s : float
    The overall normalization of the dark matter halo \
    (kappa_s = (rho_s * scale_radius)/lensing_critical_density)
inner_slope : float
    The inner slope of the dark matter halo.
scale_radius : float
    The arc-second radius where the average density within this radius is 200 times the critical density of \
    the Universe..


eta = np.multiply(<NUM_LIT:1.> / self.scale_radius, self.grid_to_grid_radii(grid))<EOL>deflection_grid = np.zeros(grid.shape[<NUM_LIT:0>])<EOL>for i in range(grid.shape[<NUM_LIT:0>]):<EOL><INDENT>deflection_grid[i] = np.multiply(<NUM_LIT> * self.kappa_s * self.scale_radius, self.deflection_func_sph(eta[i]))<EOL><DEDENT>return self.grid_to_grid_cartesian(grid, deflection_grid)<EOL>


eta = np.multiply(<NUM_LIT:1.> / self.scale_radius, self.grid_to_grid_radii(grid))<EOL>deflection_grid = np.multiply((<NUM_LIT> * self.kappa_s * self.scale_radius / eta), self.deflection_func_sph(eta))<EOL>return self.grid_to_grid_cartesian(grid, deflection_grid)<EOL>


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>kappa_s: float = <NUM_LIT>,<EOL>scale_radius: dim.Length = <NUM_LIT:1.0>):<DEDENT>

super(EllipticalNFW, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi, kappa_s=kappa_s,<EOL>inner_slope=<NUM_LIT:1.0>, scale_radius=scale_radius)<EOL>

The elliptical NFW profiles, used to fit the dark matter halo of the lens.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a).
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis.
kappa_s : float
    The overall normalization of the dark matter halo \
    (kappa_s = (rho_s * scale_radius)/lensing_critical_density)
scale_radius : float
    The arc-second radius where the average density within this radius is 200 times the critical density of \
    the Universe..


potential_grid = quad_grid(self.potential_func, <NUM_LIT:0.0>, <NUM_LIT:1.0>, grid,<EOL>args=(self.axis_ratio, self.kappa_s, self.scale_radius),<EOL>epsrel=<NUM_LIT>)[<NUM_LIT:0>]<EOL>return potential_grid<EOL>


def calculate_deflection_component(npow, index):<EOL><INDENT>deflection_grid = self.axis_ratio * grid[:, index]<EOL>deflection_grid *= quad_grid(self.deflection_func, <NUM_LIT:0.0>, <NUM_LIT:1.0>, grid,<EOL>args=(npow, self.axis_ratio, self.kappa_s,<EOL>self.scale_radius))[<NUM_LIT:0>]<EOL>return deflection_grid<EOL><DEDENT>deflection_y = calculate_deflection_component(<NUM_LIT:1.0>, <NUM_LIT:0>)<EOL>deflection_x = calculate_deflection_component(<NUM_LIT:0.0>, <NUM_LIT:1>)<EOL>return self.rotate_grid_from_profile(np.multiply(<NUM_LIT:1.0>, np.vstack((deflection_y, deflection_x)).T))<EOL>


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>kappa_s: float = <NUM_LIT>,<EOL>scale_radius: dim.Length = <NUM_LIT:1.0>):<DEDENT>

super(SphericalNFW, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, kappa_s=kappa_s,<EOL>scale_radius=scale_radius)<EOL>

The spherical NFW profiles, used to fit the dark matter halo of the lens.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
kappa_s : float
    The overall normalization of the dark matter halo \
    (kappa_s = (rho_s * scale_radius)/lensing_critical_density)
scale_radius : float
    The arc-second radius where the average density within this radius is 200 times the critical density of \
    the Universe..


eta = (<NUM_LIT:1.0> / self.scale_radius) * self.grid_to_grid_radii(grid) + <NUM_LIT><EOL>return np.real(<NUM_LIT> * self.scale_radius * self.kappa_s * self.potential_func_sph(eta))<EOL>

Calculate the potential at a given set of arc-second gridded coordinates.

Parameters
----------
grid : grids.RegularGrid
    The grid of (y,x) arc-second coordinates the deflection angles are computed on.


eta = np.multiply(<NUM_LIT:1.> / self.scale_radius, self.grid_to_grid_radii(grid=grid))<EOL>deflection_r = np.multiply(<NUM_LIT> * self.kappa_s * self.scale_radius, self.deflection_func_sph(eta))<EOL>return self.grid_to_grid_cartesian(grid, deflection_r)<EOL>

Calculate the deflection angles at a given set of arc-second gridded coordinates.

Parameters
----------
grid : grids.RegularGrid
    The grid of (y,x) arc-second coordinates the deflection angles are computed on.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>sersic_index: float = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>):<DEDENT>

super(AbstractEllipticalSersic, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi)<EOL>super(EllipticalMassProfile, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi)<EOL>self.mass_to_light_ratio = mass_to_light_ratio<EOL>self.intensity = intensity<EOL>self.effective_radius = effective_radius<EOL>self.sersic_index = sersic_index<EOL>

The Sersic mass profile, the mass profiles of the light profiles that are used to fit and subtract the lens \
model_galaxy's light.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a).
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis.
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second).
effective_radius : float
    The radius containing half the light of this profile.
sersic_index : float
    Controls the concentration of the of the profile (lower value -> less concentrated, \
    higher value -> more concentrated).
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles


return self.convergence_func(self.grid_to_eccentric_radii(grid))<EOL>

Calculate the projected convergence at a given set of arc-second gridded coordinates.

        Parameters
        ----------
        grid : grids.RegularGrid
            The grid of (y,x) arc-second coordinates the surface density is computed on.


return self.intensity * np.exp(<EOL>-self.sersic_constant * (((radius / self.effective_radius) ** (<NUM_LIT:1.> / self.sersic_index)) - <NUM_LIT:1>))<EOL>

Compute the intensity of the profile at a given radius.

        Parameters
        ----------
        radius : float
            The distance from the centre of the profile.


return (<NUM_LIT:2> * self.sersic_index) - (<NUM_LIT:1.> / <NUM_LIT>) + (<NUM_LIT> / (<NUM_LIT> * self.sersic_index)) + (<EOL><NUM_LIT> / (<NUM_LIT> * self.sersic_index ** <NUM_LIT:2>)) + (<NUM_LIT> / (<NUM_LIT> * self.sersic_index ** <NUM_LIT:3>)) - (<EOL><NUM_LIT> / (<NUM_LIT> * self.sersic_index ** <NUM_LIT:4>))<EOL>

A parameter derived from Sersic index which ensures that effective radius contains 50% of the profile's
        total integrated light.


return self.effective_radius / np.sqrt(self.axis_ratio)<EOL>

The effective_radius of a Sersic light profile is defined as the circular effective radius. This is the \
        radius within which a circular aperture contains half the profiles's total integrated light. For elliptical \
        systems, this won't robustly capture the light profile's elliptical shape.

        The elliptical effective radius instead describes the major-axis radius of the ellipse containing \
        half the light, and may be more appropriate for highly flattened systems like disk galaxies.


def calculate_deflection_component(npow, index):<EOL><INDENT>sersic_constant = self.sersic_constant<EOL>deflection_grid = self.axis_ratio * grid[:, index]<EOL>deflection_grid *= quad_grid(self.deflection_func, <NUM_LIT:0.0>, <NUM_LIT:1.0>, grid,<EOL>args=(npow, self.axis_ratio, self.intensity,<EOL>self.sersic_index, self.effective_radius,<EOL>self.mass_to_light_ratio, sersic_constant))[<NUM_LIT:0>]<EOL>return deflection_grid<EOL><DEDENT>deflection_y = calculate_deflection_component(<NUM_LIT:1.0>, <NUM_LIT:0>)<EOL>deflection_x = calculate_deflection_component(<NUM_LIT:0.0>, <NUM_LIT:1>)<EOL>return self.rotate_grid_from_profile(np.multiply(<NUM_LIT:1.0>, np.vstack((deflection_y, deflection_x)).T))<EOL>


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>sersic_index: float = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>):<DEDENT>

super(SphericalSersic, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, intensity=intensity,<EOL>effective_radius=effective_radius, sersic_index=sersic_index,<EOL>mass_to_light_ratio=mass_to_light_ratio)<EOL>

The Sersic mass profile, the mass profiles of the light profiles that are used to fit and subtract the lens
model_galaxy's light.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second)
effective_radius : float
    The circular radius containing half the light of this profile.
sersic_index : float
    Controls the concentration of the of the profile (lower value -> less concentrated, \
    higher value -> more concentrated).
mass_to_light_ratio : float
    The mass-to-light ratio of the light profile.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>):<DEDENT>

super(EllipticalExponential, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi, intensity=intensity,<EOL>effective_radius=effective_radius, sersic_index=<NUM_LIT:1.0>,<EOL>mass_to_light_ratio=mass_to_light_ratio)<EOL>

The EllipticalExponential mass profile, the mass profiles of the light profiles that are used to fit and
subtract the lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a).
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis.
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second).
effective_radius : float
    The circular radius containing half the light of this profile.
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>):<DEDENT>

super(SphericalExponential, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, intensity=intensity,<EOL>effective_radius=effective_radius,<EOL>mass_to_light_ratio=mass_to_light_ratio)<EOL>

The Exponential mass profile, the mass profiles of the light profiles that are used to fit and subtract the lens
model_galaxy's light.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second).
effective_radius : float
    The circular radius containing half the light of this profile.
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles.


super(EllipticalDevVaucouleurs, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi,<EOL>intensity=intensity, effective_radius=effective_radius,<EOL>sersic_index=<NUM_LIT>, mass_to_light_ratio=mass_to_light_ratio)<EOL>

The EllipticalDevVaucouleurs mass profile, the mass profiles of the light profiles that are used to fit and
subtract the lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a).
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis.
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second).
effective_radius : float
    The radius containing half the light of this profile.
mass_to_light_ratio : float
    The mass-to-light ratio of the light profile.


super(SphericalDevVaucouleurs, self).__init__(centre=centre, axis_ratio=<NUM_LIT:1.0>, phi=<NUM_LIT:0.0>, intensity=intensity,<EOL>effective_radius=effective_radius,<EOL>mass_to_light_ratio=mass_to_light_ratio)<EOL>

The DevVaucouleurs mass profile, the mass profiles of the light profiles that are used to fit and subtract the
lens model_galaxy's light.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second).
effective_radius : float
    The circular radius containing half the light of this profile.
mass_to_light_ratio : float
    The mass-to-light ratio of the light profiles.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>,<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>sersic_index: float = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>,<EOL>mass_to_light_gradient: float = <NUM_LIT:0.0>):<DEDENT>

super(EllipticalSersicRadialGradient, self).__init__(centre=centre, axis_ratio=axis_ratio, phi=phi,<EOL>intensity=intensity, effective_radius=effective_radius,<EOL>sersic_index=sersic_index,<EOL>mass_to_light_ratio=mass_to_light_ratio)<EOL>self.mass_to_light_gradient = mass_to_light_gradient<EOL>

Setup a Sersic mass and light profiles.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
axis_ratio : float
    Ratio of profiles ellipse's minor and major axes (b/a).
phi : float
    Rotational angle of profiles ellipse counter-clockwise from positive x-axis.
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second).
effective_radius : float
    The circular radius containing half the light of this profile.
sersic_index : float
    Controls the concentration of the of the profile (lower value -> less concentrated, \
    higher value -> more concentrated).
mass_to_light_ratio : float
    The mass-to-light ratio of the light profile.
mass_to_light_gradient : float
    The mass-to-light radial gradient.


def calculate_deflection_component(npow, index):<EOL><INDENT>sersic_constant = self.sersic_constant<EOL>deflection_grid = self.axis_ratio * grid[:, index]<EOL>deflection_grid *= quad_grid(self.deflection_func, <NUM_LIT:0.0>, <NUM_LIT:1.0>, grid,<EOL>args=(npow, self.axis_ratio, self.intensity,<EOL>self.sersic_index, self.effective_radius,<EOL>self.mass_to_light_ratio, self.mass_to_light_gradient,<EOL>sersic_constant))[<NUM_LIT:0>]<EOL>return deflection_grid<EOL><DEDENT>deflection_y = calculate_deflection_component(<NUM_LIT:1.0>, <NUM_LIT:0>)<EOL>deflection_x = calculate_deflection_component(<NUM_LIT:0.0>, <NUM_LIT:1>)<EOL>return self.rotate_grid_from_profile(np.multiply(<NUM_LIT:1.0>, np.vstack((deflection_y, deflection_x)).T))<EOL>


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>intensity: dim.Luminosity = <NUM_LIT:0.1>,<EOL>effective_radius: dim.Length = <NUM_LIT>,<EOL>sersic_index: float = <NUM_LIT>,<EOL>mass_to_light_ratio: dim.MassOverLuminosity = <NUM_LIT:1.0>,<EOL>mass_to_light_gradient: float = <NUM_LIT:0.0>):<DEDENT>

Setup a Sersic mass and light profiles.

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
intensity : float
    Overall flux intensity normalisation in the light profiles (electrons per second).
effective_radius : float
    The circular radius containing half the light of this profile.
sersic_index : float
    Controls the concentration of the of the profile (lower value -> less concentrated, \
    higher value -> more concentrated).
mass_to_light_ratio : float
    The mass-to-light ratio of the light profile.
mass_to_light_gradient : float
    The mass-to-light radial gradient.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>kappa: float = <NUM_LIT:0.0>):<DEDENT>

super(MassSheet, self).__init__(centre=centre)<EOL>self.kappa = kappa<EOL>

Represents a mass-sheet

Parameters
----------
centre: (float, float)
    The (y,x) arc-second coordinates of the profile centre.
kappa : float
    The magnitude of the convergence of the mass-sheet.


@map_types<EOL><INDENT>def __init__(self,<EOL>magnitude: float = <NUM_LIT>,<EOL>phi: float = <NUM_LIT:0.0>):<DEDENT>

super(ExternalShear, self).__init__(centre=(<NUM_LIT:0.0>, <NUM_LIT:0.0>), phi=phi, axis_ratio=<NUM_LIT:1.0>)<EOL>self.magnitude = magnitude<EOL>

An external shear term, to model the line-of-sight contribution of other galaxies / satellites.

Parameters
----------
magnitude : float
    The overall magnitude of the shear (gamma).
phi : float
    The rotation axis of the shear.


deflection_y = -np.multiply(self.magnitude, grid[:, <NUM_LIT:0>])<EOL>deflection_x = np.multiply(self.magnitude, grid[:, <NUM_LIT:1>])<EOL>return self.rotate_grid_from_profile(np.vstack((deflection_y, deflection_x)).T)<EOL>


def plot_intensities(<EOL>light_profile, grid, mask=None, extract_array_from_mask=False, zoom_around_mask=False, positions=None, <EOL>as_subplot=False,<EOL>units='<STR_LIT>', kpc_per_arcsec=None, figsize=(<NUM_LIT:7>, <NUM_LIT:7>), aspect='<STR_LIT>',<EOL>cmap='<STR_LIT>', norm='<STR_LIT>', norm_min=None, norm_max=None, linthresh=<NUM_LIT>, linscale=<NUM_LIT>,<EOL>cb_ticksize=<NUM_LIT:10>, cb_fraction=<NUM_LIT>, cb_pad=<NUM_LIT>, cb_tick_values=None, cb_tick_labels=None,<EOL>title='<STR_LIT>', titlesize=<NUM_LIT:16>, xlabelsize=<NUM_LIT:16>, ylabelsize=<NUM_LIT:16>, xyticksize=<NUM_LIT:16>,<EOL>mask_pointsize=<NUM_LIT:10>, position_pointsize=<NUM_LIT>, grid_pointsize=<NUM_LIT:1>,<EOL>output_path=None, output_format='<STR_LIT>', output_filename='<STR_LIT>'):

intensities = light_profile.intensities_from_grid(grid=grid)<EOL>intensities = grid.scaled_array_2d_from_array_1d(intensities)<EOL>array_plotters.plot_array(<EOL>array=intensities, mask=mask, extract_array_from_mask=extract_array_from_mask,<EOL>zoom_around_mask=zoom_around_mask, positions=positions, as_subplot=as_subplot,<EOL>units=units, kpc_per_arcsec=kpc_per_arcsec, figsize=figsize, aspect=aspect,<EOL>cmap=cmap, norm=norm, norm_min=norm_min, norm_max=norm_max, linthresh=linthresh, linscale=linscale,<EOL>cb_ticksize=cb_ticksize, cb_fraction=cb_fraction, cb_pad=cb_pad, <EOL>cb_tick_values=cb_tick_values, cb_tick_labels=cb_tick_labels,<EOL>title=title, titlesize=titlesize, xlabelsize=xlabelsize, ylabelsize=ylabelsize, xyticksize=xyticksize,<EOL>mask_pointsize=mask_pointsize, position_pointsize=position_pointsize, grid_pointsize=grid_pointsize,<EOL>output_path=output_path, output_format=output_format, output_filename=output_filename)<EOL>

Plot the intensities (e.g. the image) of a light profile, on a regular grid of (y,x) coordinates.

    Set *autolens.hyper.array.plotters.array_plotters* for a description of all innput parameters not described below.

    Parameters
    -----------
    light_profile : model.profiles.light_profiles.LightProfile
        The light profile whose intensities are plotted.
    grid : ndarray or hyper.array.grid_stacks.RegularGrid
        The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2)


def plot_convergence(<EOL>mass_profile, grid, mask=None, extract_array_from_mask=False, zoom_around_mask=False, positions=None, <EOL>as_subplot=False,<EOL>units='<STR_LIT>', kpc_per_arcsec=None, figsize=(<NUM_LIT:7>, <NUM_LIT:7>), aspect='<STR_LIT>',<EOL>cmap='<STR_LIT>', norm='<STR_LIT>', norm_min=None, norm_max=None, linthresh=<NUM_LIT>, linscale=<NUM_LIT>,<EOL>cb_ticksize=<NUM_LIT:10>, cb_fraction=<NUM_LIT>, cb_pad=<NUM_LIT>, cb_tick_values=None, cb_tick_labels=None,<EOL>title='<STR_LIT>', titlesize=<NUM_LIT:16>, xlabelsize=<NUM_LIT:16>, ylabelsize=<NUM_LIT:16>, xyticksize=<NUM_LIT:16>,<EOL>mask_pointsize=<NUM_LIT:10>, position_pointsize=<NUM_LIT>, grid_pointsize=<NUM_LIT:1>,<EOL>output_path=None, output_format='<STR_LIT>', output_filename='<STR_LIT>'):

convergence = mass_profile.convergence_from_grid(grid=grid)<EOL>convergence = grid.scaled_array_2d_from_array_1d(convergence)<EOL>array_plotters.plot_array(<EOL>array=convergence, mask=mask, extract_array_from_mask=extract_array_from_mask,<EOL>zoom_around_mask=zoom_around_mask, positions=positions, as_subplot=as_subplot,<EOL>units=units, kpc_per_arcsec=kpc_per_arcsec, figsize=figsize, aspect=aspect,<EOL>cmap=cmap, norm=norm, norm_min=norm_min, norm_max=norm_max, linthresh=linthresh, linscale=linscale,<EOL>cb_ticksize=cb_ticksize, cb_fraction=cb_fraction, cb_pad=cb_pad, <EOL>cb_tick_values=cb_tick_values, cb_tick_labels=cb_tick_labels,<EOL>title=title, titlesize=titlesize, xlabelsize=xlabelsize, ylabelsize=ylabelsize, xyticksize=xyticksize,<EOL>mask_pointsize=mask_pointsize, position_pointsize=position_pointsize, grid_pointsize=grid_pointsize,<EOL>output_path=output_path, output_format=output_format, output_filename=output_filename)<EOL>

Plot the convergence of a mass profile, on a regular grid of (y,x) coordinates.

    Set *autolens.hyper.array.plotters.array_plotters* for a description of all innput parameters not described below.

    Parameters
    -----------
    mass_profile : model.profiles.mass_profiles.MassProfile
        The mass profile whose convergence is plotted.
    grid : ndarray or hyper.array.grid_stacks.RegularGrid
        The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2)


def plot_potential(<EOL>mass_profile, grid, mask=None, extract_array_from_mask=False, zoom_around_mask=False, positions=None, <EOL>as_subplot=False,<EOL>units='<STR_LIT>', kpc_per_arcsec=None, figsize=(<NUM_LIT:7>, <NUM_LIT:7>), aspect='<STR_LIT>',<EOL>cmap='<STR_LIT>', norm='<STR_LIT>', norm_min=None, norm_max=None, linthresh=<NUM_LIT>, linscale=<NUM_LIT>,<EOL>cb_ticksize=<NUM_LIT:10>, cb_fraction=<NUM_LIT>, cb_pad=<NUM_LIT>, cb_tick_values=None, cb_tick_labels=None,<EOL>title='<STR_LIT>', titlesize=<NUM_LIT:16>, xlabelsize=<NUM_LIT:16>, ylabelsize=<NUM_LIT:16>, xyticksize=<NUM_LIT:16>,<EOL>mask_pointsize=<NUM_LIT:10>, position_pointsize=<NUM_LIT>, grid_pointsize=<NUM_LIT:1>,<EOL>output_path=None, output_format='<STR_LIT>', output_filename='<STR_LIT>'):

potential = mass_profile.potential_from_grid(grid=grid)<EOL>potential = grid.scaled_array_2d_from_array_1d(potential)<EOL>array_plotters.plot_array(<EOL>array=potential, mask=mask, extract_array_from_mask=extract_array_from_mask,<EOL>zoom_around_mask=zoom_around_mask, positions=positions, as_subplot=as_subplot,<EOL>units=units, kpc_per_arcsec=kpc_per_arcsec, figsize=figsize, aspect=aspect,<EOL>cmap=cmap, norm=norm, norm_min=norm_min, norm_max=norm_max, linthresh=linthresh, linscale=linscale,<EOL>cb_ticksize=cb_ticksize, cb_fraction=cb_fraction, cb_pad=cb_pad, <EOL>cb_tick_values=cb_tick_values, cb_tick_labels=cb_tick_labels,<EOL>title=title, titlesize=titlesize, xlabelsize=xlabelsize, ylabelsize=ylabelsize, xyticksize=xyticksize,<EOL>mask_pointsize=mask_pointsize, position_pointsize=position_pointsize, grid_pointsize=grid_pointsize,<EOL>output_path=output_path, output_format=output_format, output_filename=output_filename)<EOL>

Plot the potential of a mass profile, on a regular grid of (y,x) coordinates.

    Set *autolens.hyper.array.plotters.array_plotters* for a description of all innput parameters not described below.

    Parameters
    -----------
    mass_profile : model.profiles.mass_profiles.MassProfile
        The mass profile whose potential is plotted.
    grid : ndarray or hyper.array.grid_stacks.RegularGrid
        The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2)


def plot_deflections_y(<EOL>mass_profile, grid, mask=None, extract_array_from_mask=False, zoom_around_mask=False, positions=None, <EOL>as_subplot=False,<EOL>units='<STR_LIT>', kpc_per_arcsec=None, figsize=(<NUM_LIT:7>, <NUM_LIT:7>), aspect='<STR_LIT>',<EOL>cmap='<STR_LIT>', norm='<STR_LIT>', norm_min=None, norm_max=None, linthresh=<NUM_LIT>, linscale=<NUM_LIT>,<EOL>cb_ticksize=<NUM_LIT:10>, cb_fraction=<NUM_LIT>, cb_pad=<NUM_LIT>, cb_tick_values=None, cb_tick_labels=None,<EOL>title='<STR_LIT>', titlesize=<NUM_LIT:16>, xlabelsize=<NUM_LIT:16>, ylabelsize=<NUM_LIT:16>, xyticksize=<NUM_LIT:16>,<EOL>mask_pointsize=<NUM_LIT:10>, position_pointsize=<NUM_LIT>, grid_pointsize=<NUM_LIT:1>,<EOL>output_path=None, output_format='<STR_LIT>', output_filename='<STR_LIT>'):

deflections = mass_profile.deflections_from_grid(grid)<EOL>deflections_y = grid.scaled_array_2d_from_array_1d(deflections[:, <NUM_LIT:0>])<EOL>array_plotters.plot_array(<EOL>array=deflections_y, mask=mask, extract_array_from_mask=extract_array_from_mask,<EOL>zoom_around_mask=zoom_around_mask, positions=positions, as_subplot=as_subplot,<EOL>units=units, kpc_per_arcsec=kpc_per_arcsec, figsize=figsize, aspect=aspect,<EOL>cmap=cmap, norm=norm, norm_min=norm_min, norm_max=norm_max, linthresh=linthresh, linscale=linscale,<EOL>cb_ticksize=cb_ticksize, cb_fraction=cb_fraction, cb_pad=cb_pad, <EOL>cb_tick_values=cb_tick_values, cb_tick_labels=cb_tick_labels,<EOL>title=title, titlesize=titlesize, xlabelsize=xlabelsize, ylabelsize=ylabelsize, xyticksize=xyticksize,<EOL>mask_pointsize=mask_pointsize, position_pointsize=position_pointsize, grid_pointsize=grid_pointsize,<EOL>output_path=output_path, output_format=output_format, output_filename=output_filename)<EOL>

Plot the y component of the deflection angles of a mass profile, on a regular grid of (y,x) coordinates.

    Set *autolens.hyper.array.plotters.array_plotters* for a description of all innput parameters not described below.

    Parameters
    -----------
    mass_profile : model.profiles.mass_profiles.MassProfile
        The mass profile whose y deflecton angles are plotted.
    grid : ndarray or hyper.array.grid_stacks.RegularGrid
        The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2)


def plot_deflections_x(<EOL>mass_profile, grid, mask=None, extract_array_from_mask=False, zoom_around_mask=False, positions=None, <EOL>as_subplot=False,<EOL>units='<STR_LIT>', kpc_per_arcsec=None, figsize=(<NUM_LIT:7>, <NUM_LIT:7>), aspect='<STR_LIT>',<EOL>cmap='<STR_LIT>', norm='<STR_LIT>', norm_min=None, norm_max=None, linthresh=<NUM_LIT>, linscale=<NUM_LIT>,<EOL>cb_ticksize=<NUM_LIT:10>, cb_fraction=<NUM_LIT>, cb_pad=<NUM_LIT>, cb_tick_values=None, cb_tick_labels=None,<EOL>title='<STR_LIT>', titlesize=<NUM_LIT:16>, xlabelsize=<NUM_LIT:16>, ylabelsize=<NUM_LIT:16>, xyticksize=<NUM_LIT:16>,<EOL>mask_pointsize=<NUM_LIT:10>, position_pointsize=<NUM_LIT>, grid_pointsize=<NUM_LIT:1>,<EOL>output_path=None, output_format='<STR_LIT>', output_filename='<STR_LIT>'):

deflections = mass_profile.deflections_from_grid(grid)<EOL>deflections_x = grid.scaled_array_2d_from_array_1d(deflections[:, <NUM_LIT:1>])<EOL>array_plotters.plot_array(<EOL>array=deflections_x, mask=mask, extract_array_from_mask=extract_array_from_mask,<EOL>zoom_around_mask=zoom_around_mask, positions=positions, as_subplot=as_subplot,<EOL>units=units, kpc_per_arcsec=kpc_per_arcsec, figsize=figsize, aspect=aspect,<EOL>cmap=cmap, norm=norm, norm_min=norm_min, norm_max=norm_max, linthresh=linthresh, linscale=linscale,<EOL>cb_ticksize=cb_ticksize, cb_fraction=cb_fraction, cb_pad=cb_pad, <EOL>cb_tick_values=cb_tick_values, cb_tick_labels=cb_tick_labels,<EOL>title=title, titlesize=titlesize, xlabelsize=xlabelsize, ylabelsize=ylabelsize, xyticksize=xyticksize,<EOL>mask_pointsize=mask_pointsize, position_pointsize=position_pointsize, grid_pointsize=grid_pointsize,<EOL>output_path=output_path, output_format=output_format, output_filename=output_filename)<EOL>

Plot the x component of the deflection angles of a mass profile, on a regular grid of (y,x) coordinates.

     Set *autolens.hyper.array.plotters.array_plotters* for a description of all innput parameters not described below.

     Parameters
     -----------
     mass_profile : model.profiles.mass_profiles.MassProfile
         The mass profile whose x deflecton angles are plotted.
     grid : ndarray or hyper.array.grid_stacks.RegularGrid
         The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2)


@wraps(func)<EOL>def wrapper(profile, grid, *args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>if not isinstance(grid, TransformedGrid):<EOL><INDENT>return func(profile, profile.transform_grid_to_reference_frame(grid), *args, **kwargs)<EOL><DEDENT>else:<EOL><INDENT>return func(profile, grid, *args, **kwargs)<EOL><DEDENT><DEDENT>return wrapper<EOL>

Wrap the function in a function that checks whether the coordinates have been transformed. If they have not \
    been transformed then they are transformed.

    Parameters
    ----------
    func : (profiles, *args, **kwargs) -> Object
        A function that requires transformed coordinates

    Returns
    -------
        A function that can except cartesian or transformed coordinates


def wrapper(instance: GeometryProfile, grid: np.ndarray, *args, **kwargs):<EOL><INDENT>if not hasattr(instance, "<STR_LIT>"):<EOL><INDENT>instance.cache = {}<EOL><DEDENT>key = (func.__name__, grid.tobytes())<EOL>if key not in instance.cache:<EOL><INDENT>instance.cache[key] = func(instance, grid)<EOL><DEDENT>return instance.cache[key]<EOL><DEDENT>return wrapper<EOL>

Caches results of a call to a grid function. If a grid that evaluates to the same byte value is passed into the same
function of the same instance as previously then the cached result is returned.

Parameters
----------
func
    Some instance method that takes a grid as its argument

Returns
-------
result
    Some result, either newly calculated or recovered from the cache


@wraps(func)<EOL>def wrapper(profile, grid, *args, **kwargs):<EOL><INDENT>"""<STR_LIT>"""<EOL>radial_minimum_config = conf.NamedConfig(f"<STR_LIT>")<EOL>grid_radial_minimum = radial_minimum_config.get("<STR_LIT>", profile.__class__.__name__, float)<EOL>with np.errstate(all='<STR_LIT:ignore>'):  <EOL><INDENT>grid_radii = profile.grid_to_grid_radii(grid=grid)<EOL>grid_radial_scale = np.where(grid_radii < grid_radial_minimum, grid_radial_minimum / grid_radii, <NUM_LIT:1.0>)<EOL>grid = np.multiply(grid, grid_radial_scale[:, None])<EOL><DEDENT>grid[np.isnan(grid)] = grid_radial_minimum<EOL>return func(profile, grid, *args, **kwargs)<EOL><DEDENT>return wrapper<EOL>

Checks whether any coordinates in the grid are radially near (0.0, 0.0), which can lead to numerical faults in \
    the evaluation of a light or mass profiles. If any coordinates are radially within the the radial minimum \
    threshold, their (y,x) coordinates are shifted to that value to ensure they are evaluated correctly.

    By default this radial minimum is not used, and users should be certain they use a value that does not impact \
    results.

    Parameters
    ----------
    func : (profile, *args, **kwargs) -> Object
        A function that takes a grid of coordinates which may have a singularity as (0.0, 0.0)

    Returns
    -------
        A function that can except cartesian or transformed coordinates


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>)):<DEDENT>

super(GeometryProfile, self).__init__()<EOL>self.centre = centre<EOL>

An abstract geometry profile, which describes profiles with y and x centre Cartesian coordinates

        Parameters
        -----------
        centre : (float, float)
            The (y,x) arc-second coordinates of the profile centre.


super(SphericalProfile, self).__init__(centre=centre)<EOL>

A spherical profile, which describes profiles with y and x centre Cartesian coordinates.

        Parameters
        ----------
        centre: (float, float)
            The (y,x) arc-second coordinates of the profile centre.


return np.sqrt(np.add(np.square(grid[:, <NUM_LIT:0>]), np.square(grid[:, <NUM_LIT:1>])))<EOL>

Convert a grid of (y, x) coordinates to a grid of their circular radii.

        If the coordinates have not been transformed to the profile's centre, this is performed automatically.

        Parameters
        ----------
        grid : TransformedGrid(ndarray)
            The (y, x) coordinates in the reference frame of the profile.


return np.cos(grid_thetas), np.sin(grid_thetas)<EOL>

The angle between each (y,x) coordinate on the grid and the profile, in radians.

        Parameters
        -----------
        grid_thetas : ndarray
            The angle theta counter-clockwise from the positive x-axis to each coordinate in radians.


def grid_to_grid_cartesian(self, grid, radius):

grid_thetas = np.arctan2(grid[:, <NUM_LIT:0>], grid[:, <NUM_LIT:1>])<EOL>cos_theta, sin_theta = self.grid_angle_to_profile(grid_thetas=grid_thetas)<EOL>return np.multiply(radius[:, None], np.vstack((sin_theta, cos_theta)).T)<EOL>

Convert a grid of (y,x) coordinates with their specified circular radii to their original (y,x) Cartesian
coordinates.

Parameters
----------
grid : TransformedGrid(ndarray)
    The (y, x) coordinates in the reference frame of the profile.
radius : ndarray
    The circular radius of each coordinate from the profile center.


transformed = np.subtract(grid, self.centre)<EOL>return transformed.view(TransformedGrid)<EOL>

Transform a grid of (y,x) coordinates to the reference frame of the profile, including a translation to \
        its centre.

        Parameters
        ----------
        grid : ndarray
            The (y, x) coordinates in the original reference frame of the grid.


transformed = np.add(grid, self.centre)<EOL>return transformed.view(TransformedGrid)<EOL>

Transform a grid of (y,x) coordinates from the reference frame of the profile to the original observer \
        reference frame, including a translation from the profile's centre.

        Parameters
        ----------
        grid : TransformedGrid(ndarray)
            The (y, x) coordinates in the reference frame of the profile.


@map_types<EOL><INDENT>def __init__(self,<EOL>centre: dim.Position = (<NUM_LIT:0.0>, <NUM_LIT:0.0>),<EOL>axis_ratio: float = <NUM_LIT:1.0>,<EOL>phi: float = <NUM_LIT:0.0>):<DEDENT>

super(EllipticalProfile, self).__init__(centre=centre)<EOL>self.axis_ratio = axis_ratio<EOL>self.phi = phi<EOL>

An elliptical profile, which describes profiles with y and x centre Cartesian coordinates, an axis-ratio \
        and rotational angle phi.

        Parameters
        ----------
        centre: (float, float)
            The (y,x) arc-second coordinates of the profile centre.
        axis_ratio : float
            Ratio of profiles ellipse's minor and major axes (b/a)
        phi : float
            Rotation angle of profiles ellipse counter-clockwise from positive x-axis


phi_radians = np.radians(self.phi)<EOL>return np.cos(phi_radians), np.sin(phi_radians)<EOL>

Determine the sin and cosine of the angle between the profile's ellipse and the positive x-axis, \
        counter-clockwise.


theta_coordinate_to_profile = np.add(grid_thetas, - self.phi_radians)<EOL>return np.cos(theta_coordinate_to_profile), np.sin(theta_coordinate_to_profile)<EOL>

The angle between each angle theta on the grid and the profile, in radians.

        Parameters
        -----------
        grid_thetas : ndarray
            The angle theta counter-clockwise from the positive x-axis to each coordinate in radians.


y = np.add(np.multiply(grid_elliptical[:, <NUM_LIT:1>], self.sin_phi), np.multiply(grid_elliptical[:, <NUM_LIT:0>], self.cos_phi))<EOL>x = np.add(np.multiply(grid_elliptical[:, <NUM_LIT:1>], self.cos_phi), - np.multiply(grid_elliptical[:, <NUM_LIT:0>], self.sin_phi))<EOL>return np.vstack((y, x)).T<EOL>

Rotate a grid of elliptical (y,x) coordinates from the reference frame of the profile back to the \
        unrotated coordinate grid reference frame (coordinates are not shifted back to their original centre).

        This routine is used after computing deflection angles in the reference frame of the profile, so that the \
        deflection angles can be re-rotated to the frame of the original coordinates before performing ray-tracing.

        Parameters
        ----------
        grid_elliptical : TransformedGrid(ndarray)
            The (y, x) coordinates in the reference frame of an elliptical profile.


return np.sqrt(np.add(np.square(grid[:, <NUM_LIT:1>]), np.square(np.divide(grid[:, <NUM_LIT:0>], self.axis_ratio))))<EOL>

Convert a grid of (y,x) coordinates to an elliptical radius.

        If the coordinates have not been transformed to the profile's geometry, this is performed automatically.

        Parameters
        ----------
        grid : TransformedGrid(ndarray)
            The (y, x) coordinates in the reference frame of the elliptical profile.