Instruction:
Write a Python 3 script to
load a noise - map from a. fits file.

Response:
def load_noise_map(noise_map_path, noise_map_hdu, pixel_scale, image, background_noise_map, exposure_time_map,
                   convert_noise_map_from_weight_map, convert_noise_map_from_inverse_noise_map,
                   noise_map_from_image_and_background_noise_map, convert_from_electrons, gain, convert_from_adus):
    """Factory for loading the noise-map from a .fits file.

    This factory also includes a number of routines for converting the noise-map from from other units (e.g. \
    a weight map) or computing the noise-map from other unblurred_image_1d (e.g. the ccd image and background noise-map).

    Parameters
    ----------
    noise_map_path : str
        The path to the noise_map .fits file containing the noise_map (e.g. '/path/to/noise_map.fits')
    noise_map_hdu : int
        The hdu the noise_map is contained in the .fits file specified by *noise_map_path*.
    pixel_scale : float
        The size of each pixel in arc seconds.
    image : ndarray
        The image-image, which the noise-map can be calculated using.
    background_noise_map : ndarray
        The background noise-map, which the noise-map can be calculated using.
    exposure_time_map : ndarray
        The exposure-time map, which the noise-map can be calculated using.
    convert_noise_map_from_weight_map : bool
        If True, the noise-map loaded from the .fits file is converted from a weight-map to a noise-map (see \
        *NoiseMap.from_weight_map).
    convert_noise_map_from_inverse_noise_map : bool
        If True, the noise-map loaded from the .fits file is converted from an inverse noise-map to a noise-map (see \
        *NoiseMap.from_inverse_noise_map).
    background_noise_map_path : str
        The path and filename of the .fits image containing the background noise-map.
    background_noise_map_hdu : int
        The hdu the background noise-map is contained in the .fits file that *background_noise_map_path* points too.
    convert_background_noise_map_from_weight_map : bool
        If True, the bacground noise-map loaded from the .fits file is converted from a weight-map to a noise-map (see \
        *NoiseMap.from_weight_map).
    convert_background_noise_map_from_inverse_noise_map : bool
        If True, the background noise-map loaded from the .fits file is converted from an inverse noise-map to a \
        noise-map (see *NoiseMap.from_inverse_noise_map).
    noise_map_from_image_and_background_noise_map : bool
        If True, the noise-map is computed from the observed image and background noise-map \
        (see NoiseMap.from_image_and_background_noise_map).
    convert_from_electrons : bool
        If True, the input unblurred_image_1d are in units of electrons and all converted to electrons / second using the exposure \
        time map.
    gain : float
        The image gain, used for convert from ADUs.
    convert_from_adus : bool
        If True, the input unblurred_image_1d are in units of adus and all converted to electrons / second using the exposure \
        time map and gain.
    """
    noise_map_options = sum([convert_noise_map_from_weight_map,
                             convert_noise_map_from_inverse_noise_map,
                             noise_map_from_image_and_background_noise_map])

    if noise_map_options > 1:
        raise exc.DataException('You have specified more than one method to load the noise_map map, e.g.:'
                                   'convert_noise_map_from_weight_map | '
                                   'convert_noise_map_from_inverse_noise_map |'
                                   'noise_map_from_image_and_background_noise_map')

    if noise_map_options == 0 and noise_map_path is not None:
        return NoiseMap.from_fits_with_pixel_scale(file_path=noise_map_path, hdu=noise_map_hdu, pixel_scale=pixel_scale)
    elif convert_noise_map_from_weight_map and noise_map_path is not None:
        weight_map = Array.from_fits(file_path=noise_map_path, hdu=noise_map_hdu)
        return NoiseMap.from_weight_map(weight_map=weight_map, pixel_scale=pixel_scale)
    elif convert_noise_map_from_inverse_noise_map and noise_map_path is not None:
        inverse_noise_map = Array.from_fits(file_path=noise_map_path, hdu=noise_map_hdu)
        return NoiseMap.from_inverse_noise_map(inverse_noise_map=inverse_noise_map, pixel_scale=pixel_scale)
    elif noise_map_from_image_and_background_noise_map:

        if background_noise_map is None:
            raise exc.DataException('Cannot compute the noise-map from the image and background noise_map map if a '
                                       'background noise_map map is not supplied.')

        if not (convert_from_electrons or convert_from_adus) and exposure_time_map is None:
            raise exc.DataException('Cannot compute the noise-map from the image and background noise_map map if an '
                                       'exposure-time (or exposure time map) is not supplied to convert to adus')

        if convert_from_adus and gain is None:
            raise exc.DataException('Cannot compute the noise-map from the image and background noise_map map if a'
                                       'gain is not supplied to convert from adus')

        return NoiseMap.from_image_and_background_noise_map(pixel_scale=pixel_scale, image=image,
                                                            background_noise_map=background_noise_map,
                                                            exposure_time_map=exposure_time_map,
                                                            convert_from_electrons=convert_from_electrons,
                                                            gain=gain, convert_from_adus=convert_from_adus)
    else:
        raise exc.DataException(
            'A noise_map map was not loaded, specify a noise_map_path or option to compute a noise_map map.')


Instruction:
Given the following Python 3 function, write the documentation
def load_background_noise_map(background_noise_map_path, background_noise_map_hdu, pixel_scale,
                              convert_background_noise_map_from_weight_map,
                              convert_background_noise_map_from_inverse_noise_map):
    """Factory for loading the background noise-map from a .fits file.

    This factory also includes a number of routines for converting the background noise-map from from other units (e.g. \
    a weight map).

    Parameters
    ----------
    background_noise_map_path : str
        The path to the background_noise_map .fits file containing the background noise-map \
        (e.g. '/path/to/background_noise_map.fits')
    background_noise_map_hdu : int
        The hdu the background_noise_map is contained in the .fits file specified by *background_noise_map_path*.
    pixel_scale : float
        The size of each pixel in arc seconds.
    convert_background_noise_map_from_weight_map : bool
        If True, the bacground noise-map loaded from the .fits file is converted from a weight-map to a noise-map (see \
        *NoiseMap.from_weight_map).
    convert_background_noise_map_from_inverse_noise_map : bool
        If True, the background noise-map loaded from the .fits file is converted from an inverse noise-map to a \
        noise-map (see *NoiseMap.from_inverse_noise_map).
    """
    background_noise_map_options = sum([convert_background_noise_map_from_weight_map,
                                        convert_background_noise_map_from_inverse_noise_map])

    if background_noise_map_options == 0 and background_noise_map_path is not None:
        return NoiseMap.from_fits_with_pixel_scale(file_path=background_noise_map_path, hdu=background_noise_map_hdu,
                                                   pixel_scale=pixel_scale)
    elif convert_background_noise_map_from_weight_map and background_noise_map_path is not None:
        weight_map = Array.from_fits(file_path=background_noise_map_path, hdu=background_noise_map_hdu)
        return NoiseMap.from_weight_map(weight_map=weight_map, pixel_scale=pixel_scale)
    elif convert_background_noise_map_from_inverse_noise_map and background_noise_map_path is not None:
        inverse_noise_map = Array.from_fits(file_path=background_noise_map_path, hdu=background_noise_map_hdu)
        return NoiseMap.from_inverse_noise_map(inverse_noise_map=inverse_noise_map, pixel_scale=pixel_scale)
    else:
        return None

Response: Load the background noise - map from a. fits file.


Instruction:
Here you have a function in Python 3, explain what it does
def load_poisson_noise_map(poisson_noise_map_path, poisson_noise_map_hdu, pixel_scale,
                           convert_poisson_noise_map_from_weight_map,
                           convert_poisson_noise_map_from_inverse_noise_map,
                           poisson_noise_map_from_image,
                           image, exposure_time_map, convert_from_electrons, gain, convert_from_adus):
    """Factory for loading the Poisson noise-map from a .fits file.

    This factory also includes a number of routines for converting the Poisson noise-map from from other units (e.g. \
    a weight map) or computing the Poisson noise_map from other unblurred_image_1d (e.g. the ccd image).

    Parameters
    ----------
    poisson_noise_map_path : str
        The path to the poisson_noise_map .fits file containing the Poisson noise-map \
         (e.g. '/path/to/poisson_noise_map.fits')
    poisson_noise_map_hdu : int
        The hdu the poisson_noise_map is contained in the .fits file specified by *poisson_noise_map_path*.
    pixel_scale : float
        The size of each pixel in arc seconds.
    convert_poisson_noise_map_from_weight_map : bool
        If True, the Poisson noise-map loaded from the .fits file is converted from a weight-map to a noise-map (see \
        *NoiseMap.from_weight_map).
    convert_poisson_noise_map_from_inverse_noise_map : bool
        If True, the Poisson noise-map loaded from the .fits file is converted from an inverse noise-map to a \
        noise-map (see *NoiseMap.from_inverse_noise_map).
    poisson_noise_map_from_image : bool
        If True, the Poisson noise-map is estimated using the image.
    image : ndarray
        The image, which the Poisson noise-map can be calculated using.
    background_noise_map : ndarray
        The background noise-map, which the Poisson noise-map can be calculated using.
    exposure_time_map : ndarray
        The exposure-time map, which the Poisson noise-map can be calculated using.
    convert_from_electrons : bool
        If True, the input unblurred_image_1d are in units of electrons and all converted to electrons / second using the exposure \
        time map.
    gain : float
        The image gain, used for convert from ADUs.
    convert_from_adus : bool
        If True, the input unblurred_image_1d are in units of adus and all converted to electrons / second using the exposure \
        time map and gain.
    """
    poisson_noise_map_options = sum([convert_poisson_noise_map_from_weight_map,
                                     convert_poisson_noise_map_from_inverse_noise_map,
                                     poisson_noise_map_from_image])

    if poisson_noise_map_options == 0 and poisson_noise_map_path is not None:
        return PoissonNoiseMap.from_fits_with_pixel_scale(file_path=poisson_noise_map_path, hdu=poisson_noise_map_hdu,
                                                          pixel_scale=pixel_scale)
    elif poisson_noise_map_from_image:

        if not (convert_from_electrons or convert_from_adus) and exposure_time_map is None:
            raise exc.DataException('Cannot compute the Poisson noise-map from the image if an '
                                       'exposure-time (or exposure time map) is not supplied to convert to adus')

        if convert_from_adus and gain is None:
            raise exc.DataException('Cannot compute the Poisson noise-map from the image if a'
                                       'gain is not supplied to convert from adus')

        return PoissonNoiseMap.from_image_and_exposure_time_map(pixel_scale=pixel_scale, image=image,
                                                                exposure_time_map=exposure_time_map,
                                                                convert_from_electrons=convert_from_electrons,
                                                                gain=gain,
                                                                convert_from_adus=convert_from_adus)

    elif convert_poisson_noise_map_from_weight_map and poisson_noise_map_path is not None:
        weight_map = Array.from_fits(file_path=poisson_noise_map_path, hdu=poisson_noise_map_hdu)
        return PoissonNoiseMap.from_weight_map(weight_map=weight_map, pixel_scale=pixel_scale)
    elif convert_poisson_noise_map_from_inverse_noise_map and poisson_noise_map_path is not None:
        inverse_noise_map = Array.from_fits(file_path=poisson_noise_map_path, hdu=poisson_noise_map_hdu)
        return PoissonNoiseMap.from_inverse_noise_map(inverse_noise_map=inverse_noise_map, pixel_scale=pixel_scale)
    else:
        return None

Response: Load the Poisson noise - map from a. fits file.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def load_background_sky_map(background_sky_map_path, background_sky_map_hdu, pixel_scale):
    if background_sky_map_path is not None:
        return ScaledSquarePixelArray.from_fits_with_pixel_scale(file_path=background_sky_map_path,
                                                                 hdu=background_sky_map_hdu, pixel_scale=pixel_scale)
    else:
        return None

Response: Factory for loading the background sky map from a. fits file.


Instruction:
Can you tell what is the following Python 3 function doing
def load_positions(positions_path):
    with open(positions_path) as f:
        position_string = f.readlines()

    positions = []

    for line in position_string:
        position_list = ast.literal_eval(line)
        positions.append(position_list)

    return positions

Response: Loads the positions of an image from a. dat file.


Instruction:
Write a Python 3 function that can
output the positions of an image to a positions. dat file.

Response:
def output_positions(positions, positions_path):
    """Output the positions of an image to a positions.dat file.

    Positions correspond to a set of pixels in the lensed source galaxy that are anticipated to come from the same \
    multiply-imaged region of the source-plane. Mass models which do not trace the pixels within a threshold value of \
    one another are resampled during the non-linear search.

    Positions are stored in a .dat file, where each line of the file gives a list of list of (y,x) positions which \
    correspond to the same region of the source-plane. Thus, multiple source-plane regions can be input over multiple \
    lines of the same positions file.

    Parameters
    ----------
    positions : [[[]]]
        The lists of positions (e.g. [[[1.0, 1.0], [2.0, 2.0]], [[3.0, 3.0], [4.0, 4.0]]])
    positions_path : str
        The path to the positions .dat file containing the positions (e.g. '/path/to/positions.dat')
    """
    with open(positions_path, 'w') as f:
        for position in positions:
            f.write("%s\n" % position)


Instruction:
Write a Python 3 function that can
simulate a set of variable arrays.

Response:
def simulate_variable_arrays(cls, array, pixel_scale, exposure_time_map, psf=None, background_sky_map=None,
                                 add_noise=True, noise_if_add_noise_false=0.1, noise_seed=-1, name=None):
        """
        Create a realistic simulated image by applying effects to a plain simulated image.

        Parameters
        ----------
        name
        array : ndarray
            The image before simulating (e.g. the lens and source galaxies before optics blurring and CCD read-out).
        pixel_scale: float
            The scale of each pixel in arc seconds
        exposure_time_map : ndarray
            An array representing the effective exposure time of each pixel.
        psf: PSF
            An array describing the PSF the simulated image is blurred with.
        background_sky_map : ndarray
            The value of background sky in every image pixel (electrons per second).
        add_noise: Bool
            If True poisson noise_maps is simulated and added to the image, based on the total counts in each image
            pixel
        noise_seed: int
            A seed for random noise_maps generation
        """

        if background_sky_map is not None:
            array += background_sky_map

        if psf is not None:
            array = psf.convolve(array)
            array = cls.trim_psf_edges(array, psf)
            exposure_time_map = cls.trim_psf_edges(exposure_time_map, psf)
            if background_sky_map is not None:
                background_sky_map = cls.trim_psf_edges(background_sky_map, psf)

        if add_noise is True:
            array += generate_poisson_noise(array, exposure_time_map, noise_seed)
            array_counts = np.multiply(array, exposure_time_map)
            noise_map = np.divide(np.sqrt(array_counts), exposure_time_map)
        else:
            noise_map = noise_if_add_noise_false * np.ones(array.shape)

        if np.isnan(noise_map).any():
            raise exc.DataException('The noise-map has NaN values in it. This suggests your exposure time and / or'
                                       'background sky levels are too low, create signal counts at or close to 0.0.')

        if background_sky_map is not None:
            array -= background_sky_map

        # ESTIMATE THE BACKGROUND NOISE MAP FROM THE IMAGE

        if background_sky_map is not None:
            background_noise_map_counts = np.sqrt(np.multiply(background_sky_map, exposure_time_map))
            background_noise_map = np.divide(background_noise_map_counts, exposure_time_map)
        else:
            background_noise_map = None

        # ESTIMATE THE POISSON NOISE MAP FROM THE IMAGE

        array_counts = np.multiply(array, exposure_time_map)
        poisson_noise_map = np.divide(np.sqrt(np.abs(array_counts)), exposure_time_map)

        array = ScaledSquarePixelArray(array=array, pixel_scale=pixel_scale)
        noise_map = NoiseMap(array=noise_map, pixel_scale=pixel_scale)

        if background_noise_map is not None:
            background_noise_map = NoiseMap(array=background_noise_map, pixel_scale=pixel_scale)

        if poisson_noise_map is not None:
            poisson_noise_map = PoissonNoiseMap(array=poisson_noise_map, pixel_scale=pixel_scale)

        return CCDData(array, pixel_scale=pixel_scale, psf=psf, noise_map=noise_map,
                       background_noise_map=background_noise_map, poisson_noise_map=poisson_noise_map,
                       exposure_time_map=exposure_time_map, background_sky_map=background_sky_map, name=name)


Instruction:
Write a Python 3 script for
creating a realistic simulated image by applying effects to the target signal to noise.

Response:
def simulate_to_target_signal_to_noise(cls, array, pixel_scale, target_signal_to_noise, exposure_time_map,
                                           psf=None, background_sky_map=None, seed=-1):
        """
        Create a realistic simulated image by applying effects to a plain simulated image.

        Parameters
        ----------
        target_signal_to_noise
        array : ndarray
            The image before simulating (e.g. the lens and source galaxies before optics blurring and CCD read-out).
        pixel_scale: float
            The scale of each pixel in arc seconds
        exposure_time_map : ndarray
            An array representing the effective exposure time of each pixel.
        psf: PSF
            An array describing the PSF the simulated image is blurred with.
        background_sky_map : ndarray
            The value of background sky in every image pixel (electrons per second).
        seed: int
            A seed for random noise_maps generation
        """

        max_index = np.unravel_index(array.argmax(), array.shape)
        max_image = array[max_index]
        max_effective_exposure_time = exposure_time_map[max_index]
        max_array_counts = np.multiply(max_image, max_effective_exposure_time)
        if background_sky_map is not None:
            max_background_sky_map = background_sky_map[max_index]
            max_background_sky_map_counts = np.multiply(max_background_sky_map, max_effective_exposure_time)
        else:
            max_background_sky_map_counts = None

        scale_factor = 1.

        if background_sky_map is None:
            scale_factor = target_signal_to_noise ** 2.0 / max_array_counts
        elif background_sky_map is not None:
            scale_factor = (max_array_counts + max_background_sky_map_counts) * target_signal_to_noise ** 2.0 \
                           / max_array_counts ** 2.0

        scaled_effective_exposure_time = np.multiply(scale_factor, exposure_time_map)

        return cls.simulate_variable_arrays(array=array, pixel_scale=pixel_scale,
                                            exposure_time_map=scaled_effective_exposure_time,
                                            psf=psf, background_sky_map=background_sky_map,
                                            add_noise=True, noise_seed=seed)


Instruction:
Can you create a Python 3 function that
converts the array from adus to electrons per second.

Response:
def array_from_adus_to_electrons_per_second(self, array, gain):
        """
        For an array (in counts) and an exposure time mappers, convert the array to units electrons per second

        Parameters
        ----------
        array : ndarray
            The array the values are to be converted from counts to electrons per second.
        """
        if array is not None:
            return np.divide(gain * array, self.exposure_time_map)
        else:
            return None


Instruction:
Explain what the following Python 3 code does
def estimated_noise_map_counts(self):
        return np.sqrt((np.abs(self.image_counts) + np.square(self.background_noise_map_counts)))

Response:
The estimated noise_maps mappers of the image using its background noise_maps mappers and image values
        in counts.


Instruction:
Make a summary of the following Python 3 code
def background_noise_from_edges(self, no_edges):

        edges = []

        for edge_no in range(no_edges):
            top_edge = self.image[edge_no, edge_no:self.image.shape[1] - edge_no]
            bottom_edge = self.image[self.image.shape[0] - 1 - edge_no, edge_no:self.image.shape[1] - edge_no]
            left_edge = self.image[edge_no + 1:self.image.shape[0] - 1 - edge_no, edge_no]
            right_edge = self.image[edge_no + 1:self.image.shape[0] - 1 - edge_no, self.image.shape[1] - 1 - edge_no]

            edges = np.concatenate((edges, top_edge, bottom_edge, right_edge, left_edge))

        return norm.fit(edges)[1]

Response: Estimate the background signal_to_noise_ratio by binning data_to_image located at the edge of an image and fitting a Gaussian profile to this histogram.


Instruction:
Can you write a function in Python 3 where it
simulates the PSF as an elliptical Gaussian profile.

Response:
def simulate_as_gaussian(cls, shape, pixel_scale, sigma, centre=(0.0, 0.0), axis_ratio=1.0, phi=0.0):
        """Simulate the PSF as an elliptical Gaussian profile."""
        from autolens.model.profiles.light_profiles import EllipticalGaussian
        gaussian = EllipticalGaussian(centre=centre, axis_ratio=axis_ratio, phi=phi, intensity=1.0, sigma=sigma)
        grid_1d = grid_util.regular_grid_1d_masked_from_mask_pixel_scales_and_origin(mask=np.full(shape, False),
                                                                                pixel_scales=(
                                                                                pixel_scale, pixel_scale))
        gaussian_1d = gaussian.intensities_from_grid(grid=grid_1d)
        gaussian_2d = mapping_util.map_unmasked_1d_array_to_2d_array_from_array_1d_and_shape(array_1d=gaussian_1d,
                                                                                shape=shape)
        return PSF(array=gaussian_2d, pixel_scale=pixel_scale, renormalize=True)


Instruction:
Can you implement a function in Python 3 that
loads a PSF from a. fits file and renormalizes it.

Response:
def from_fits_renormalized(cls, file_path, hdu, pixel_scale):
        """Loads a PSF from fits and renormalizes it

        Parameters
        ----------
        pixel_scale
        file_path: String
            The path to the file containing the PSF
        hdu : int
            The HDU the PSF is stored in the .fits file.

        Returns
        -------
        psf: PSF
            A renormalized PSF instance
        """
        psf = PSF.from_fits_with_scale(file_path, hdu, pixel_scale)
        psf[:, :] = np.divide(psf, np.sum(psf))
        return psf


Instruction:
How would you explain what the following Python 3 function does
def from_fits_with_scale(cls, file_path, hdu, pixel_scale):
        return cls(array=array_util.numpy_array_2d_from_fits(file_path, hdu), pixel_scale=pixel_scale)

Response: Loads the PSF from a. fits file.


Instruction:
Given the following Python 3 function, write the documentation
def new_psf_with_renormalized_array(self):
        return PSF(array=self, pixel_scale=self.pixel_scale, renormalize=True)

Response: Return a new PSF with the data_vector values sum to unity.


Instruction:
Make a summary of the following Python 3 code
def convolve(self, array):
        if self.shape[0] % 2 == 0 or self.shape[1] % 2 == 0:
            raise exc.KernelException("PSF Kernel must be odd")

        return scipy.signal.convolve2d(array, self, mode='same')

Response: Convolve an array with this PSF


Instruction:
How would you implement a function in Python 3 that
calculates the image - plane pixelization from a regular - grid of coordinates and its mask.

Response:
def image_plane_pix_grid_from_regular_grid(self, regular_grid):
        """Calculate the image-plane pixelization from a regular-grid of coordinates (and its mask).

        See *grid_stacks.SparseToRegularGrid* for details on how this grid is calculated.

        Parameters
        -----------
        regular_grid : grids.RegularGrid
            The grid of (y,x) arc-second coordinates at the centre of every image value (e.g. image-pixels).
        """

        pixel_scale = regular_grid.mask.pixel_scale

        pixel_scales = ((regular_grid.masked_shape_arcsec[0] + pixel_scale) / (self.shape[0]),
                        (regular_grid.masked_shape_arcsec[1] + pixel_scale) / (self.shape[1]))

        return grids.SparseToRegularGrid(unmasked_sparse_grid_shape=self.shape, pixel_scales=pixel_scales,
                                         regular_grid=regular_grid, origin=regular_grid.mask.centre)


Instruction:
Given the following Python 3 function, write the documentation
def geometry_from_grid(self, grid, buffer=1e-8):
        y_min = np.min(grid[:, 0]) - buffer
        y_max = np.max(grid[:, 0]) + buffer
        x_min = np.min(grid[:, 1]) - buffer
        x_max = np.max(grid[:, 1]) + buffer
        pixel_scales = (float((y_max - y_min) / self.shape[0]), float((x_max - x_min) / self.shape[1]))
        origin = ((y_max + y_min) / 2.0, (x_max + x_min) / 2.0)
        pixel_neighbors, pixel_neighbors_size = self.neighbors_from_pixelization()
        return self.Geometry(shape=self.shape, pixel_scales=pixel_scales, origin=origin,
                             pixel_neighbors=pixel_neighbors, pixel_neighbors_size=pixel_neighbors_size)

Response: Determine the geometry of the rectangular grid.


Instruction:
Make a summary of the following Python 3 code
def mapper_from_grid_stack_and_border(self, grid_stack, border):

        if border is not None:
            relocated_grid_stack = border.relocated_grid_stack_from_grid_stack(grid_stack)
        else:
            relocated_grid_stack = grid_stack

        geometry = self.geometry_from_grid(grid=relocated_grid_stack.sub)

        return mappers.RectangularMapper(pixels=self.pixels, grid_stack=relocated_grid_stack, border=border,
                                         shape=self.shape, geometry=geometry)

Response: Setup a rectangular mapper from a grid - stack and a border.


Instruction:
Write a Python 3 function that can
determine the geometry of the Voronoi pixelization, by alligning it with the outer-most coordinates on a \ grid plus a small buffer. Parameters ----------- grid : ndarray The (y,x) grid of coordinates which determine the Voronoi pixelization's geometry. pixel_centres : ndarray The (y,x) centre of every Voronoi pixel in arc-seconds. origin : (float, float) The arc-second origin of the Voronoi pixelization's coordinate system. pixel_neighbors : ndarray An array of length (voronoi_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 (voronoi_pixels) which gives the number of neighbors of every pixel in the \ Voronoi grid.

Response:
def geometry_from_grid(self, grid, pixel_centres, pixel_neighbors, pixel_neighbors_size, buffer=1e-8):
        """Determine the geometry of the Voronoi pixelization, by alligning it with the outer-most coordinates on a \
        grid plus a small buffer.

        Parameters
        -----------
        grid : ndarray
            The (y,x) grid of coordinates which determine the Voronoi pixelization's geometry.
        pixel_centres : ndarray
            The (y,x) centre of every Voronoi pixel in arc-seconds.
        origin : (float, float)
            The arc-second origin of the Voronoi pixelization's coordinate system.
        pixel_neighbors : ndarray
            An array of length (voronoi_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 (voronoi_pixels) which gives the number of neighbors of every pixel in the \
            Voronoi grid.
        """
        y_min = np.min(grid[:, 0]) - buffer
        y_max = np.max(grid[:, 0]) + buffer
        x_min = np.min(grid[:, 1]) - buffer
        x_max = np.max(grid[:, 1]) + buffer
        shape_arcsec = (y_max - y_min, x_max - x_min)
        origin = ((y_max + y_min) / 2.0, (x_max + x_min) / 2.0)
        return self.Geometry(shape_arcsec=shape_arcsec, pixel_centres=pixel_centres, origin=origin,
                             pixel_neighbors=pixel_neighbors, pixel_neighbors_size=pixel_neighbors_size)


Instruction:
Given the following Python 3 function, write the documentation
def voronoi_from_pixel_centers(pixel_centers):
        return scipy.spatial.Voronoi(np.asarray([pixel_centers[:, 1], pixel_centers[:, 0]]).T,
                                     qhull_options='Qbb Qc Qx Qm')

Response: Compute the Voronoi grid of the pixelization using the pixel centers.


Instruction:
How would you explain what the following Python 3 function does
def neighbors_from_pixelization(self, pixels, ridge_points):
        return pixelization_util.voronoi_neighbors_from_pixels_and_ridge_points(pixels=pixels,
                                                                                ridge_points=np.asarray(ridge_points))

Response: Compute the neighbors of every Voronoi pixel and the ridge points of each Voronoi vertex with.


Instruction:
Given the following Python 3 function, write the documentation
def mapper_from_grid_stack_and_border(self, grid_stack, border):

        if border is not None:
            relocated_grids = border.relocated_grid_stack_from_grid_stack(grid_stack)
        else:
            relocated_grids = grid_stack

        pixel_centres = relocated_grids.pix
        pixels = pixel_centres.shape[0]

        voronoi = self.voronoi_from_pixel_centers(pixel_centres)

        pixel_neighbors, pixel_neighbors_size = self.neighbors_from_pixelization(pixels=pixels,
                                                                                ridge_points=voronoi.ridge_points)
        geometry = self.geometry_from_grid(grid=relocated_grids.sub, pixel_centres=pixel_centres,
                                           pixel_neighbors=pixel_neighbors,
                                           pixel_neighbors_size=pixel_neighbors_size)

        return mappers.VoronoiMapper(pixels=pixels, grid_stack=relocated_grids, border=border,
                                     voronoi=voronoi, geometry=geometry)

Response: Setup a Voronoi mapper from a grid - stack and a border.


Instruction:
Can you write a function in Python 3 where it
plots a grid of y and x coordinates.

Response:
def plot_grid(grid, axis_limits=None, points=None, as_subplot=False,
              units='arcsec', kpc_per_arcsec=None,
              figsize=(12, 8), pointsize=5, pointcolor='k', xyticksize=16,
              title='Grid', titlesize=16, xlabelsize=16, ylabelsize=16,
              output_path=None, output_format='show', output_filename='grid'):
    """Plot a grid of (y,x) Cartesian coordinates as a scatter plot of points.

    Parameters
    -----------
    grid : data.array.grids.RegularGrid
        The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2).
    axis_limits : []
        The axis limits of the figure on which the grid is plotted, following [xmin, xmax, ymin, ymax].
    points : []
        A set of points that are plotted in a different colour for emphasis (e.g. to show the mappings between \
        different planes).
    as_subplot : bool
        Whether the grid is plotted as part of a subplot, in which case the grid figure is not opened / closed.
    units : str
        The units of the y / x axis of the plots, in arc-seconds ('arcsec') or kiloparsecs ('kpc').
    kpc_per_arcsec : float
        The conversion factor between arc-seconds and kiloparsecs, required to plot the units in kpc.
    figsize : (int, int)
        The size of the figure in (rows, columns).
    pointsize : int
        The size of the points plotted on the grid.
    xyticksize : int
        The font size of the x and y ticks on the figure axes.
    title : str
        The text of the title.
    titlesize : int
        The size of of the title of the figure.
    xlabelsize : int
        The fontsize of the x axes label.
    ylabelsize : int
        The fontsize of the y axes label.
    output_path : str
        The path on the hard-disk where the figure is output.
    output_filename : str
        The filename of the figure that is output.
    output_format : str
        The format the figue is output:
        'show' - display on computer screen.
        'png' - output to hard-disk as a png.
    """

    plotter_util.setup_figure(figsize=figsize, as_subplot=as_subplot)
    grid = convert_grid_units(grid_arcsec=grid, units=units, kpc_per_arcsec=kpc_per_arcsec)
    plt.scatter(y=np.asarray(grid[:, 0]), x=np.asarray(grid[:, 1]), s=pointsize, marker='.')
    plotter_util.set_title(title=title, titlesize=titlesize)
    set_xy_labels(units, kpc_per_arcsec, xlabelsize, ylabelsize, xyticksize)

    set_axis_limits(axis_limits)
    plot_points(grid, points, pointcolor)

    plt.tick_params(labelsize=xyticksize)
    plotter_util.output_figure(None, as_subplot, output_path, output_filename, output_format)
    plotter_util.close_figure(as_subplot=as_subplot)


Instruction:
Implement a Python 3 function for
converting the grid from its input units ( arc - seconds or convert to the input units ( kpc_per_arcsec.

Response:
def convert_grid_units(grid_arcsec, units, kpc_per_arcsec):
    """Convert the grid from its input units (arc-seconds) to the input unit (e.g. retain arc-seconds) or convert to \
    another set of units (kiloparsecs).

    Parameters
    -----------
    grid_arcsec : ndarray or data.array.grids.RegularGrid
        The (y,x) coordinates of the grid in arc-seconds, in an array of shape (total_coordinates, 2).
    units : str
        The units of the y / x axis of the plots, in arc-seconds ('arcsec') or kiloparsecs ('kpc').
    kpc_per_arcsec : float
        The conversion factor between arc-seconds and kiloparsecs, required to plot the units in kpc.
    """

    if units in 'arcsec' or kpc_per_arcsec is None:
        return grid_arcsec
    elif units in 'kpc':
        return grid_arcsec * kpc_per_arcsec


Instruction:
Can you implement a function in Python 3 that
sets the x and y labels of the base class of the base class of the base class of the base class of the base class of the base class of the base class.

Response:
def set_xy_labels(units, kpc_per_arcsec, xlabelsize, ylabelsize, xyticksize):
    """Set the x and y labels of the figure, and set the fontsize of those labels.

    The x and y labels are always the distance scales, thus the labels are either arc-seconds or kpc and depend on the \
    units the figure is plotted in.

    Parameters
    -----------
    units : str
        The units of the y / x axis of the plots, in arc-seconds ('arcsec') or kiloparsecs ('kpc').
    kpc_per_arcsec : float
        The conversion factor between arc-seconds and kiloparsecs, required to plot the units in kpc.
    xlabelsize : int
        The fontsize of the x axes label.
    ylabelsize : int
        The fontsize of the y axes label.
    xyticksize : int
        The font size of the x and y ticks on the figure axes.
    """
    if units in 'arcsec' or kpc_per_arcsec is None:

        plt.xlabel('x (arcsec)', fontsize=xlabelsize)
        plt.ylabel('y (arcsec)', fontsize=ylabelsize)

    elif units in 'kpc':

        plt.xlabel('x (kpc)', fontsize=xlabelsize)
        plt.ylabel('y (kpc)', fontsize=ylabelsize)

    else:
        raise exc.PlottingException('The units supplied to the plotted are not a valid string (must be pixels | '
                                     'arcsec | kpc)')

    plt.tick_params(labelsize=xyticksize)


Instruction:
How would you implement a function in Python 3 that
plots a subset of points in a different color for emphasis.

Response:
def plot_points(grid, points, pointcolor):
    """Plot a subset of points in a different color, to highlight a specifc region of the grid (e.g. how certain \
    pixels map between different planes).

    Parameters
    -----------
    grid : ndarray or data.array.grids.RegularGrid
        The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2).
    points : []
        A set of points that are plotted in a different colour for emphasis (e.g. to show the mappings between \
        different planes).
    pointcolor : str or None
        The color the points should be plotted. If None, the points are iterated through a cycle of colors.
    """
    if points is not None:

        if pointcolor is None:

            point_colors = itertools.cycle(["y", "r", "k", "g", "m"])
            for point_set in points:
                plt.scatter(y=np.asarray(grid[point_set, 0]),
                            x=np.asarray(grid[point_set, 1]), s=8, color=next(point_colors))

        else:

            for point_set in points:
                plt.scatter(y=np.asarray(grid[point_set, 0]),
                            x=np.asarray(grid[point_set, 1]), s=8, color=pointcolor)


Instruction:
Explain what the following Python 3 code does
def sub_to_image_grid(func):

    @wraps(func)
    def wrapper(grid, galaxies, *args, **kwargs):
        """

        Parameters
        ----------
        grid : RegularGrid
            The (y,x) coordinates of the grid, in an array of shape (total_coordinates, 2).
        galaxies : [Galaxy]
            The list of galaxies a profile quantity (e.g. intensities) is computed for which is rebinned if it \
            is a sub-grid.

        Returns
        -------
        ndarray
            If a RegularGrid is input, the profile quantity of the galaxy (e.g. intensities) evaluated using this grid.

            If a SubGrid is input, the profile quantity of the galaxy (e.g. intensities) evaluated using the sub-grid \
            and rebinned to the regular-grids array dimensions.

        Examples
        ---------
        @grids.sub_to_image_grid
        def intensities_of_galaxies_from_grid(grid, galaxies):
            return sum(map(lambda g: g.intensities_from_grid(grid), galaxies))

        galaxy_util.intensities_of_galaxies_from_grid(grid=grid_stack.sub, galaxies=galaxies)
        """

        result = func(grid, galaxies, *args, *kwargs)

        if isinstance(grid, SubGrid):
            return grid.regular_data_1d_from_sub_data_1d(result)
        else:
            return result

    return wrapper

Response: Decorator that converts a function that requires the sub - grid and galaxies and returns the summed sum of each set of sub - gridded values.


Instruction:
Explain what the following Python 3 code does
def grid_interpolate(func):

    @wraps(func)
    def wrapper(profile, grid, grid_radial_minimum=None, *args, **kwargs):
        if hasattr(grid, "interpolator"):
            interpolator = grid.interpolator
            if grid.interpolator is not None:
                values = func(profile, interpolator.interp_grid, grid_radial_minimum, *args, **kwargs)
                if values.ndim == 1:
                    return interpolator.interpolated_values_from_values(values=values)
                elif values.ndim == 2:
                    y_values = interpolator.interpolated_values_from_values(values=values[:, 0])
                    x_values = interpolator.interpolated_values_from_values(values=values[:, 1])
                    return np.asarray([y_values, x_values]).T
        return func(profile, grid, grid_radial_minimum, *args, **kwargs)

    return wrapper

Response: Decorate a profile method that accepts a coordinate grid and returns a data grid.


Instruction:
Can you generate the documentation for the following Python 3 function
def unmasked_blurred_image_from_psf_and_unmasked_image(self, psf, unmasked_image_1d):
        blurred_image_1d = self.regular.convolve_array_1d_with_psf(padded_array_1d=unmasked_image_1d,
                                                                   psf=psf)

        return self.regular.scaled_array_2d_from_array_1d(array_1d=blurred_image_1d)

Response: For a padded grid - stack and psf compute an unmasked blurred image.


Instruction:
Make a summary of the following Python 3 code
def grid_stack_for_simulation(cls, shape, pixel_scale, psf_shape, sub_grid_size=2):
        return cls.padded_grid_stack_from_mask_sub_grid_size_and_psf_shape(mask=msk.Mask(array=np.full(shape, False),
                                                                                pixel_scale=pixel_scale),
                                                                           sub_grid_size=sub_grid_size,
                                                                           psf_shape=psf_shape)

Response: Setup a grid - stack of an image of a strong lens whereby the grid s use the PSF blurring in the simulation routine.


Instruction:
Here you have a function in Python 3, explain what it does
def new_grid_stack_with_pix_grid_added(self, pix_grid, regular_to_nearest_pix):
        pix = PixGrid(arr=pix_grid, regular_to_nearest_pix=regular_to_nearest_pix)
        return GridStack(regular=self.regular, sub=self.sub, blurring=self.blurring, pix=pix)

Response: Setup a new grid - stack with a grid - stack of pixels added.


Instruction:
Can you write a function in Python 3 where it
applies a function to all grid - stacks in the grid - stack.

Response:
def apply_function(self, func):
        """Apply a function to all grid_stack in the grid-stack.

        This is used by the *ray-tracing* module to easily apply tracing operations to all grid_stack."""
        if self.blurring is not None and self.pix is not None:
            return GridStack(func(self.regular), func(self.sub), func(self.blurring), func(self.pix))
        elif self.blurring is None and self.pix is not None:
            return GridStack(func(self.regular), func(self.sub), self.blurring, func(self.pix))
        elif self.blurring is not None and self.pix is None:
            return GridStack(func(self.regular), func(self.sub), func(self.blurring), self.pix)
        else:
            return GridStack(func(self.regular), func(self.sub), self.blurring, self.pix)


Instruction:
Write a Python 3 script for
mapping a function to all grid_stacks in a grid - stack

Response:
def map_function(self, func, *arg_lists):
        """Map a function to all grid_stack in a grid-stack"""
        return GridStack(*[func(*args) for args in zip(self, *arg_lists)])


Instruction:
Explain what the following Python 3 code does
def convolve_array_1d_with_psf(self, padded_array_1d, psf):
        padded_array_2d = mapping_util.map_unmasked_1d_array_to_2d_array_from_array_1d_and_shape(
            array_1d=padded_array_1d, shape=self.mask.shape)
        # noinspection PyUnresolvedReferences
        blurred_padded_array_2d = psf.convolve(array=padded_array_2d)
        return mapping_util.map_2d_array_to_masked_1d_array_from_array_2d_and_mask(array_2d=blurred_padded_array_2d,
                                                                                mask=np.full(self.mask.shape, False))

Response: Convolve a 1d padded array of values with a PSF.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def blurring_grid_from_mask_and_psf_shape(cls, mask, psf_shape):
        blurring_mask = mask.blurring_mask_for_psf_shape(psf_shape)
        return RegularGrid.from_mask(blurring_mask)

Response: Setup a blurring - grid from a mask and a PSF shape.


Instruction:
Can you generate the documentation for the following Python 3 function
def array_2d_from_array_1d(self, array_1d):
        return mapping_util.map_masked_1d_array_to_2d_array_from_array_1d_shape_and_one_to_two(
            array_1d=array_1d, shape=self.mask.shape, one_to_two=self.mask.masked_grid_index_to_pixel)

Response: Maps a 1D array to its original masked 2D array.


Instruction:
Can you write a function in Python 3 where it
maps a 1D array to its original masked 2D array and return a scaled 2D array.

Response:
def scaled_array_2d_from_array_1d(self, array_1d):
        """ Map a 1D array the same dimension as the grid to its original masked 2D array and return it as a scaled \
        array.

        Parameters
        -----------
        array_1d : ndarray
            The 1D array of which is mapped to a 2D scaled array.
        """
        return scaled_array.ScaledSquarePixelArray(array=self.array_2d_from_array_1d(array_1d),
                                                   pixel_scale=self.mask.pixel_scale,
                                                   origin=self.mask.origin)


Instruction:
Here you have a function in Python 3, explain what it does
def yticks(self):
        return np.linspace(np.min(self[:, 0]), np.max(self[:, 0]), 4)

Response: Compute the y - axis ticks of this grid used for plotting the y - axis ticks when visualizing a regular grid


Instruction:
Create a Python 3 function to
compute the x - axis ticks labels of this grid used for plotting the x - axis ticks when visualizing a regular grid

Response:
def xticks(self):
        """Compute the xticks labels of this grid, used for plotting the x-axis ticks when visualizing a regular"""
        return np.linspace(np.min(self[:, 1]), np.max(self[:, 1]), 4)


Instruction:
Explain what the following Python 3 code does
def from_mask_and_sub_grid_size(cls, mask, sub_grid_size=1):
        sub_grid_masked = grid_util.sub_grid_1d_masked_from_mask_pixel_scales_and_sub_grid_size(
            mask=mask,
            pixel_scales=mask.pixel_scales,
            sub_grid_size=sub_grid_size)
        return SubGrid(sub_grid_masked, mask, sub_grid_size)

Response: Setup a sub - grid of the unmasked pixels using a mask and a sub - grid size.


Instruction:
How would you explain what the following Python 3 function does
def sub_array_2d_from_sub_array_1d(self, sub_array_1d):
        sub_shape = (self.mask.shape[0] * self.sub_grid_size, self.mask.shape[1] * self.sub_grid_size)
        sub_one_to_two = self.mask.masked_sub_grid_index_to_sub_pixel(sub_grid_size=self.sub_grid_size)
        return mapping_util.map_masked_1d_array_to_2d_array_from_array_1d_shape_and_one_to_two(
            array_1d=sub_array_1d, shape=sub_shape, one_to_two=sub_one_to_two)

Response: Maps a 1D sub - array to its original 2D sub - array.


Instruction:
Make a summary of the following Python 3 code
def scaled_array_2d_with_sub_dimensions_from_sub_array_1d(self, sub_array_1d):
        return scaled_array.ScaledSquarePixelArray(array=self.sub_array_2d_from_sub_array_1d(sub_array_1d=sub_array_1d),
                                                   pixel_scale=self.mask.pixel_scale / self.sub_grid_size,
                                                   origin=self.mask.origin)

Response: Returns a 2D sub - array with the same dimensions as the sub - grid and the dimensions of the original 1D sub - array.


Instruction:
Implement a function in Python 3 to
map a 1D sub - array to its original masked 2D sub - array and return it as a scaled array.

Response:
def scaled_array_2d_with_regular_dimensions_from_binned_up_sub_array_1d(self, sub_array_1d):
        """ Map a 1D sub-array the same dimension as the sub-grid to its original masked 2D sub-array and return it as
        a scaled array.

        Parameters
        -----------
        sub_array_1d : ndarray
            The 1D sub-array of which is mapped to a 2D scaled sub-array the dimensions.
        """
        array_1d = self.regular_data_1d_from_sub_data_1d(sub_array_1d=sub_array_1d)
        return scaled_array.ScaledSquarePixelArray(array=self.array_2d_from_array_1d(array_1d=array_1d),
                                                   pixel_scale=self.mask.pixel_scale,
                                                   origin=self.mask.origin)


Instruction:
Here you have a function in Python 3, explain what it does
def unmasked_sparse_to_sparse(self):

        return mapping_util.unmasked_sparse_to_sparse_from_mask_and_pixel_centres(
            mask=self.regular_grid.mask,
            unmasked_sparse_grid_pixel_centres=self.unmasked_sparse_grid_pixel_centres,
            total_sparse_pixels=self.total_sparse_pixels).astype(
            'int')

Response: The 1D index mappings between the unmasked sparse - grid and masked sparse - grid.


Instruction:
Make a summary of the following Python 3 code
def sparse_to_unmasked_sparse(self):
        return mapping_util.sparse_to_unmasked_sparse_from_mask_and_pixel_centres(
            total_sparse_pixels=self.total_sparse_pixels, mask=self.regular_grid.mask,
            unmasked_sparse_grid_pixel_centres=self.unmasked_sparse_grid_pixel_centres).astype('int')

Response: The 1D index mappings between the masked sparse - grid and unmasked sparse - grid.


Instruction:
Explain what the following Python 3 code does
def sparse_grid(self):
        return mapping_util.sparse_grid_from_unmasked_sparse_grid(
            unmasked_sparse_grid=self.unmasked_sparse_grid,
            sparse_to_unmasked_sparse=self.sparse_to_unmasked_sparse)

Response: The y - second coordinates of the masked sparse - grid.


Instruction:
How would you implement a function in Python 3 that
computes a 2D padded blurred image from a 1D padded image and a PSF.

Response:
def padded_blurred_image_2d_from_padded_image_1d_and_psf(self, padded_image_1d, psf):
        """Compute a 2D padded blurred image from a 1D padded image.

        Parameters
        ----------
        padded_image_1d : ndarray
            A 1D unmasked image which is blurred with the PSF.
        psf : ndarray
            An array describing the PSF kernel of the image.
        """
        padded_model_image_1d = self.convolve_array_1d_with_psf(padded_array_1d=padded_image_1d, psf=psf)
        return self.scaled_array_2d_from_array_1d(array_1d=padded_model_image_1d)


Instruction:
Here you have a function in Python 3, explain what it does
def array_2d_from_array_1d(self, padded_array_1d):
        padded_array_2d = self.map_to_2d_keep_padded(padded_array_1d)
        pad_size_0 = self.mask.shape[0] - self.image_shape[0]
        pad_size_1 = self.mask.shape[1] - self.image_shape[1]
        return (padded_array_2d[pad_size_0 // 2:self.mask.shape[0] - pad_size_0 // 2,
                pad_size_1 // 2:self.mask.shape[1] - pad_size_1 // 2])

Response: Map a padded 1D array of values to its original 2D array trimming all edge values.


Instruction:
Given the following Python 3 function, write the documentation
def map_to_2d_keep_padded(self, padded_array_1d):
        return mapping_util.map_unmasked_1d_array_to_2d_array_from_array_1d_and_shape(array_1d=padded_array_1d,
                                                                                shape=self.mask.shape)

Response: Map a padded 1D array of values to its padded 2D array.


Instruction:
Can you tell what is the following Python 3 function doing
def padded_grid_from_mask_sub_grid_size_and_psf_shape(cls, mask, sub_grid_size, psf_shape):

        padded_shape = (mask.shape[0] + psf_shape[0] - 1, mask.shape[1] + psf_shape[1] - 1)

        padded_sub_grid = grid_util.sub_grid_1d_masked_from_mask_pixel_scales_and_sub_grid_size(
            mask=np.full(padded_shape, False), pixel_scales=mask.pixel_scales, sub_grid_size=sub_grid_size)

        padded_mask = msk.Mask.unmasked_for_shape_and_pixel_scale(shape=padded_shape, pixel_scale=mask.pixel_scale)

        return PaddedSubGrid(arr=padded_sub_grid, mask=padded_mask, image_shape=mask.shape,
                             sub_grid_size=sub_grid_size)

Response: Setup an * PaddedSubGrid* for an input mask sub - grid size and psf - shape.


Instruction:
Can you generate the documentation for the following Python 3 function
def relocated_grid_stack_from_grid_stack(self, grid_stack):
        border_grid = grid_stack.regular[self]
        return GridStack(regular=self.relocated_grid_from_grid_jit(grid=grid_stack.regular, border_grid=border_grid),
                         sub=self.relocated_grid_from_grid_jit(grid=grid_stack.sub, border_grid=border_grid),
                         blurring=None,
                         pix=self.relocated_grid_from_grid_jit(grid=grid_stack.pix, border_grid=border_grid))

Response: Return a grid_stack that contains the pixels relocated based on the borders of the input grid_stack.


Instruction:
Can you implement a function in Python 3 that
relocates the coordinates of a grid to its border if they are outside the border.

Response:
def relocated_grid_from_grid_jit(grid, border_grid):
        """ Relocate the coordinates of a grid to its border if they are outside the border. This is performed as \
        follows:

        1) Use the mean value of the grid's y and x coordinates to determine the origin of the grid.
        2) Compute the radial distance of every grid coordinate from the origin.
        3) For every coordinate, find its nearest pixel in the border.
        4) Determine if it is outside the border, by comparing its radial distance from the origin to its paid \
           border pixel's radial distance.
        5) If its radial distance is larger, use the ratio of radial distances to move the coordinate to the border \
           (if its inside the border, do nothing).
        """
        border_origin = np.zeros(2)
        border_origin[0] = np.mean(border_grid[:, 0])
        border_origin[1] = np.mean(border_grid[:, 1])
        border_grid_radii = np.sqrt(np.add(np.square(np.subtract(border_grid[:, 0], border_origin[0])),
                                           np.square(np.subtract(border_grid[:, 1], border_origin[1]))))
        border_min_radii = np.min(border_grid_radii)

        grid_radii = np.sqrt(np.add(np.square(np.subtract(grid[:, 0], border_origin[0])),
                                    np.square(np.subtract(grid[:, 1], border_origin[1]))))

        for pixel_index in range(grid.shape[0]):

            if grid_radii[pixel_index] > border_min_radii:

                closest_pixel_index = np.argmin(np.square(grid[pixel_index, 0] - border_grid[:, 0]) +
                                                np.square(grid[pixel_index, 1] - border_grid[:, 1]))

                move_factor = border_grid_radii[closest_pixel_index] / grid_radii[pixel_index]
                if move_factor < 1.0:
                    grid[pixel_index, :] = move_factor * (grid[pixel_index, :] - border_origin[:]) + border_origin[:]

        return grid


Instruction:
Given the following Python 3 function, write the documentation
def run(self, positions, pixel_scale, results=None):
        analysis = self.make_analysis(positions=positions, pixel_scale=pixel_scale, results=results)
        result = self.run_analysis(analysis)
        return self.make_result(result, analysis)

Response: Runs the next phase and returns the result.


Instruction:
Write a Python 3 function that can
create an analysis object for this object.

Response:
def make_analysis(self, positions, pixel_scale, results=None):
        """
        Create an lens object. Also calls the prior passing and lens_data modifying functions to allow child
        classes to change the behaviour of the phase.

        Parameters
        ----------
        pixel_scale
        positions
        results: autofit.tools.pipeline.ResultsCollection
            The result from the previous phase

        Returns
        -------
        lens: Analysis
            An lens object that the non-linear optimizer calls to determine the fit of a set of values
        """
        self.pass_priors(results)
        analysis = self.__class__.Analysis(positions=positions, pixel_scale=pixel_scale, cosmology=self.cosmology,
                                           results=results)
        return analysis


Instruction:
Given the following Python 3 function, write the documentation
def run(self, data, results=None, mask=None, positions=None):
        analysis = self.make_analysis(data=data, results=results, mask=mask, positions=positions)

        result = self.run_analysis(analysis)

        return self.make_result(result, analysis)

Response: Runs the next phase.


Instruction:
Can you implement a function in Python 3 that
creates an analysis object for the child phase.

Response:
def make_analysis(self, data, results=None, mask=None, positions=None):
        """
        Create an lens object. Also calls the prior passing and lens_data modifying functions to allow child
        classes to change the behaviour of the phase.

        Parameters
        ----------
        positions
        mask: Mask
            The default masks passed in by the pipeline
        data: im.CCD
            An lens_data that has been masked
        results: autofit.tools.pipeline.ResultsCollection
            The result from the previous phase

        Returns
        -------
        lens : Analysis
            An lens object that the non-linear optimizer calls to determine the fit of a set of values
        """

        mask = setup_phase_mask(data=data, mask=mask, mask_function=self.mask_function,
                                inner_mask_radii=self.inner_mask_radii)

        if self.positions_threshold is not None and positions is not None:
            positions = list(map(lambda position_set: np.asarray(position_set), positions))
        elif self.positions_threshold is None:
            positions = None
        elif self.positions_threshold is not None and positions is None:
            raise exc.PhaseException('You have specified for a phase to use positions, but not input positions to the '
                                     'pipeline when you ran it.')

        lens_data = li.LensData(ccd_data=data, mask=mask, sub_grid_size=self.sub_grid_size,
                                image_psf_shape=self.image_psf_shape, positions=positions,
                                interp_pixel_scale=self.interp_pixel_scale)

        modified_image = self.modify_image(image=lens_data.image, results=results)
        lens_data = lens_data.new_lens_data_with_modified_image(modified_image=modified_image)

        if self.bin_up_factor is not None:
            lens_data = lens_data.new_lens_data_with_binned_up_ccd_data_and_mask(bin_up_factor=self.bin_up_factor)

        self.pass_priors(results)

        self.output_phase_info()

        analysis = self.__class__.Analysis(lens_data=lens_data, cosmology=self.cosmology,
                                           positions_threshold=self.positions_threshold, results=results)
        return analysis


Instruction:
Write a Python 3 script for
running the next phase and returns the result object.

Response:
def run(self, galaxy_data, results=None, mask=None):
        """
        Run this phase.

        Parameters
        ----------
        galaxy_data
        mask: Mask
            The default masks passed in by the pipeline
        results: autofit.tools.pipeline.ResultsCollection
            An object describing the results of the last phase or None if no phase has been executed

        Returns
        -------
        result: AbstractPhase.Result
            A result object comprising the best fit model and other hyper.
        """
        analysis = self.make_analysis(galaxy_data=galaxy_data, results=results, mask=mask)
        result = self.run_analysis(analysis)

        return self.make_result(result, analysis)


Instruction:
How would you explain what the following Python 3 function does
def run(self, data, results=None, mask=None, positions=None):
        model_image = results.last.unmasked_model_image
        galaxy_tuples = results.last.constant.name_instance_tuples_for_class(g.Galaxy)

        results_copy = copy.copy(results.last)

        for name, galaxy in galaxy_tuples:
            optimizer = self.optimizer.copy_with_name_extension(name)
            optimizer.variable.hyper_galaxy = g.HyperGalaxy
            galaxy_image = results.last.unmasked_image_for_galaxy(galaxy)
            optimizer.fit(self.__class__.Analysis(data, model_image, galaxy_image))

            getattr(results_copy.variable, name).hyper_galaxy = optimizer.variable.hyper_galaxy
            getattr(results_copy.constant, name).hyper_galaxy = optimizer.constant.hyper_galaxy

        return results_copy

Response: Run a fit for each galaxy from the previous phase.


Instruction:
Write a Python 3 script for
mapping 1D pixel indexes to 2D pixel indexes.

Response:
def map_1d_indexes_to_2d_indexes_for_shape(indexes_1d, shape):
    """For pixels on a 2D array of shape (rows, colums), map an array of 1D pixel indexes to 2D pixel indexes.

    Indexing is defined from the top-left corner rightwards and downwards, whereby the top-left pixel on the 2D array
    corresponds to index 0, the pixel to its right pixel 1, and so on.

    For a 2D array of shape (3,3), 1D pixel indexes are converted as follows:

    - 1D Pixel index 0 maps -> 2D pixel index [0,0].
    - 1D Pixel index 1 maps -> 2D pixel index [0,1].
    - 1D Pixel index 4 maps -> 2D pixel index [1,0].
    - 1D Pixel index 8 maps -> 2D pixel index [2,2].

    Parameters
     ----------
    indexes_1d : ndarray
        The 1D pixel indexes which are mapped to 2D indexes.
    shape : (int, int)
        The shape of the 2D array which the pixels are defined on.

    Returns
    --------
    ndarray
        An array of 2d pixel indexes with dimensions (total_indexes, 2).

    Examples
    --------
    indexes_1d = np.array([0, 1, 2, 5])
    indexes_2d = map_1d_indexes_to_2d_indexes_for_shape(indexes_1d=indexes_1d, shape=(3,3))
    """
    indexes_2d = np.zeros((indexes_1d.shape[0], 2))

    for i, index_1d in enumerate(indexes_1d):
        indexes_2d[i, 0] = int(index_1d / shape[1])
        indexes_2d[i, 1] = int(index_1d % shape[1])

    return indexes_2d


Instruction:
Can you tell what is the following Python 3 function doing
def map_2d_indexes_to_1d_indexes_for_shape(indexes_2d, shape):
    indexes_1d = np.zeros(indexes_2d.shape[0])

    for i in range(indexes_2d.shape[0]):
        indexes_1d[i] = int((indexes_2d[i, 0]) * shape[1] + indexes_2d[i, 1])

    return indexes_1d

Response: Maps a 2D array of indexes to 1D indexes.


Instruction:
How would you explain what the following Python 3 function does
def map_masked_1d_array_to_2d_array_from_array_1d_shape_and_one_to_two(array_1d, shape, one_to_two):

    array_2d = np.zeros(shape)

    for index in range(len(one_to_two)):
        array_2d[one_to_two[index, 0], one_to_two[index, 1]] = array_1d[index]

    return array_2d

Response: This function maps unmasked values from a 1D array to a 2D array where masked values are set to zero.


Instruction:
Make a summary of the following Python 3 code
def map_unmasked_1d_array_to_2d_array_from_array_1d_and_shape(array_1d, shape):

    array_2d = np.zeros(shape)

    index = 0
    for y in range(shape[0]):
        for x in range(shape[1]):
            array_2d[y, x] = array_1d[index]
            index += 1

    return array_2d

Response: This function maps a 1D array to a 2D array.


Instruction:
Explain what the following Python 3 code does
def sparse_to_unmasked_sparse_from_mask_and_pixel_centres(total_sparse_pixels, mask,
                                                          unmasked_sparse_grid_pixel_centres):
    """Determine the mapping between every masked pixelization-grid pixel and pixelization-grid pixel. This is
    performed by checking whether each pixelization-grid pixel is within the regular-masks, and mapping the indexes.

    Parameters
    -----------
    total_sparse_pixels : int
        The total number of pixels in the pixelization grid which fall within the regular-masks.
    mask : ccd.masks.Mask
        The regular-masks within which pixelization pixels must be inside
    unmasked_sparse_grid_pixel_centres : ndarray
        The centres of the unmasked pixelization grid pixels.
    """

    pix_to_full_pix = np.zeros(total_sparse_pixels)

    pixel_index = 0

    for full_pixel_index in range(unmasked_sparse_grid_pixel_centres.shape[0]):

        y = unmasked_sparse_grid_pixel_centres[full_pixel_index, 0]
        x = unmasked_sparse_grid_pixel_centres[full_pixel_index, 1]

        if not mask[y, x]:
            pix_to_full_pix[pixel_index] = full_pixel_index
            pixel_index += 1

    return pix_to_full_pix

Response: This function returns a sparse matrix that maps every pixel in the unmasked pixelization - grid pixel to the full - pixels of the unmasked pixelization - grid pixel.


Instruction:
Write a Python 3 script for
determining the mapping between every pixelization-grid pixel and masked pixelization-grid pixel. This is performed by checking whether each pixelization-grid pixel is within the regular-masks, and mapping the indexes. Pixelization pixels are paired with the next masked pixel index. This may mean that a pixel is not paired with a pixel near it, if the next pixel is on the next row of the grid. This is not a problem, as it is only unmasked pixels that are referened when computing image_to_pix, which is what this array is used for. Parameters ----------- total_sparse_pixels : int The total number of pixels in the pixelization grid which fall within the regular-masks. mask : ccd.masks.Mask The regular-masks within which pixelization pixels must be inside unmasked_sparse_grid_pixel_centres : ndarray The centres of the unmasked pixelization grid pixels.

Response:
def unmasked_sparse_to_sparse_from_mask_and_pixel_centres(mask, unmasked_sparse_grid_pixel_centres,
                                                          total_sparse_pixels):
    """Determine the mapping between every pixelization-grid pixel and masked pixelization-grid pixel. This is
    performed by checking whether each pixelization-grid pixel is within the regular-masks, and mapping the indexes.

    Pixelization pixels are paired with the next masked pixel index. This may mean that a pixel is not paired with a
    pixel near it, if the next pixel is on the next row of the grid. This is not a problem, as it is only
    unmasked pixels that are referened when computing image_to_pix, which is what this array is used for.

    Parameters
    -----------
    total_sparse_pixels : int
        The total number of pixels in the pixelization grid which fall within the regular-masks.
    mask : ccd.masks.Mask
        The regular-masks within which pixelization pixels must be inside
    unmasked_sparse_grid_pixel_centres : ndarray
        The centres of the unmasked pixelization grid pixels.
    """

    total_unmasked_sparse_pixels = unmasked_sparse_grid_pixel_centres.shape[0]

    unmasked_sparse_to_sparse = np.zeros(total_unmasked_sparse_pixels)
    pixel_index = 0

    for unmasked_sparse_pixel_index in range(total_unmasked_sparse_pixels):

        y = unmasked_sparse_grid_pixel_centres[unmasked_sparse_pixel_index, 0]
        x = unmasked_sparse_grid_pixel_centres[unmasked_sparse_pixel_index, 1]

        unmasked_sparse_to_sparse[unmasked_sparse_pixel_index] = pixel_index

        if not mask[y, x]:
            if pixel_index < total_sparse_pixels - 1:
                pixel_index += 1

    return unmasked_sparse_to_sparse


Instruction:
Given the following Python 3 function, write the documentation
def regular_to_sparse_from_sparse_mappings(regular_to_unmasked_sparse, unmasked_sparse_to_sparse):
    total_regular_pixels = regular_to_unmasked_sparse.shape[0]

    regular_to_sparse = np.zeros(total_regular_pixels)

    for regular_index in range(total_regular_pixels):
    #    print(regular_index, regular_to_unmasked_sparse[regular_index], unmasked_sparse_to_sparse.shape[0])
        regular_to_sparse[regular_index] = unmasked_sparse_to_sparse[regular_to_unmasked_sparse[regular_index]]

    return regular_to_sparse

Response: This function computes the index mapping between the regular and unmasked pixelizations grid and the unmasked sparse grid.


Instruction:
Can you generate the documentation for the following Python 3 function
def sparse_grid_from_unmasked_sparse_grid(unmasked_sparse_grid, sparse_to_unmasked_sparse):
    total_pix_pixels = sparse_to_unmasked_sparse.shape[0]

    pix_grid = np.zeros((total_pix_pixels, 2))

    for pixel_index in range(total_pix_pixels):
        pix_grid[pixel_index, 0] = unmasked_sparse_grid[sparse_to_unmasked_sparse[pixel_index], 0]
        pix_grid[pixel_index, 1] = unmasked_sparse_grid[sparse_to_unmasked_sparse[pixel_index], 1]

    return pix_grid

Response: This function returns a sparse grid from the unmasked pixelization grid.


Instruction:
Write a Python 3 script to
bin up an array to coarser resolution using the mean value of the new pixel.

Response:
def bin_up_array_2d_using_mean(array_2d, bin_up_factor):
    """Bin up an array to coarser resolution, by binning up groups of pixels and using their mean value to determine \
     the value of the new pixel.

    If an array of shape (8,8) is input and the bin up size is 2, this would return a new array of size (4,4) where \
    every pixel was the mean of each collection of 2x2 pixels on the (8,8) array.

    If binning up the array leads to an edge being cut (e.g. a (9,9) array binned up by 2), an array is first \
    extracted around the centre of that array.

    Parameters
    ----------
    array_2d : ndarray
        The 2D array that is resized.
    new_shape : (int, int)
        The (y,x) new pixel dimension of the trimmed array.
    origin : (int, int)
        The oigin of the resized array, e.g. the central pixel around which the array is extracted.

    Returns
    -------
    ndarray
        The resized 2D array from the input 2D array.

    Examples
    --------
    array_2d = np.ones((5,5))
    resize_array = resize_array_2d(array_2d=array_2d, new_shape=(2,2), origin=(2, 2))
    """

    padded_array_2d = pad_2d_array_for_binning_up_with_bin_up_factor(array_2d=array_2d, bin_up_factor=bin_up_factor)

    binned_array_2d = np.zeros(shape=(padded_array_2d.shape[0] // bin_up_factor,
                                      padded_array_2d.shape[1] // bin_up_factor))

    for y in range(binned_array_2d.shape[0]):
        for x in range(binned_array_2d.shape[1]):
            value = 0.0
            for y1 in range(bin_up_factor):
                for x1 in range(bin_up_factor):
                    padded_y = y*bin_up_factor + y1
                    padded_x = x*bin_up_factor + x1
                    value += padded_array_2d[padded_y, padded_x]

            binned_array_2d[y,x] = value / (bin_up_factor ** 2.0)

    return binned_array_2d


Instruction:
Write a Python 3 script for
writing a 2D NumPy array to a. fits file.

Response:
def numpy_array_2d_to_fits(array_2d, file_path, overwrite=False):
    """Write a 2D NumPy array to a .fits file.

    Before outputting a NumPy array, the array is flipped upside-down using np.flipud. This is so that the arrays \
    appear the same orientation as .fits files loaded in DS9.

    Parameters
    ----------
    array_2d : ndarray
        The 2D array that is written to fits.
    file_path : str
        The full path of the file that is output, including the file name and '.fits' extension.
    overwrite : bool
        If True and a file already exists with the input file_path the .fits file is overwritten. If False, an error \
        will be raised.

    Returns
    -------
    None

    Examples
    --------
    array_2d = np.ones((5,5))
    numpy_array_to_fits(array=array_2d, file_path='/path/to/file/filename.fits', overwrite=True)
    """
    if overwrite and os.path.exists(file_path):
        os.remove(file_path)

    new_hdr = fits.Header()
    hdu = fits.PrimaryHDU(np.flipud(array_2d), new_hdr)
    hdu.writeto(file_path)


Instruction:
How would you explain what the following Python 3 function does
def numpy_array_2d_from_fits(file_path, hdu):
    hdu_list = fits.open(file_path)
    return np.flipud(np.array(hdu_list[hdu].data))

Response: Read a 2D NumPy array to a. fits file.


Instruction:
Write a Python 3 function for
plotting the lens subtracted image of a specific fit.

Response:
def plot_lens_subtracted_image(
        fit, mask=None, extract_array_from_mask=False, zoom_around_mask=False, positions=None, as_subplot=False,
        units='arcsec', kpc_per_arcsec=None, figsize=(7, 7), aspect='square',
        cmap='jet', norm='linear', norm_min=None, norm_max=None, linthresh=0.05, linscale=0.01,
        cb_ticksize=10, cb_fraction=0.047, cb_pad=0.01, cb_tick_values=None, cb_tick_labels=None,
        title='Fit Model Image', titlesize=16, xlabelsize=16, ylabelsize=16, xyticksize=16,
        mask_pointsize=10, position_pointsize=10,
        output_path=None, output_format='show', output_filename='fit_lens_subtracted_image'):
    """Plot the model image of a specific plane of a lens fit.

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

    Parameters
    -----------
    fit : datas.fitting.fitting.AbstractFitter
        The fit to the datas, which includes a list of every model image, residual_map, chi-squareds, etc.
    image_index : int
        The index of the datas in the datas-set of which the model image is plotted.
    plane_indexes : int
        The plane from which the model image is generated.
    """

    if fit.tracer.total_planes == 2:
        if fit.tracer.image_plane.has_light_profile:
            lens_subtracted_image = fit.image - fit.model_image_of_planes[0]
        else:
            lens_subtracted_image = fit.image
    else:
        lens_subtracted_image = fit.image - sum(fit.model_image_of_planes[0:-2])

    array_plotters.plot_array(
        array=lens_subtracted_image, mask=mask, extract_array_from_mask=extract_array_from_mask,
        zoom_around_mask=zoom_around_mask, positions=positions, as_subplot=as_subplot,
        units=units, kpc_per_arcsec=kpc_per_arcsec, figsize=figsize, aspect=aspect,
        cmap=cmap, norm=norm, norm_min=norm_min, norm_max=norm_max, linthresh=linthresh, linscale=linscale,
        cb_ticksize=cb_ticksize, cb_fraction=cb_fraction, cb_pad=cb_pad,
        cb_tick_values=cb_tick_values, cb_tick_labels=cb_tick_labels,
        title=title, titlesize=titlesize, xlabelsize=xlabelsize, ylabelsize=ylabelsize, xyticksize=xyticksize,
        mask_pointsize=mask_pointsize, position_pointsize=position_pointsize,
        output_path=output_path, output_format=output_format, output_filename=output_filename)


Instruction:
Explain what the following Python 3 code does
def plot_model_image_of_planes(
        fit, plot_foreground=False, plot_source=False, mask=None, extract_array_from_mask=False, zoom_around_mask=False,
        positions=None, plot_mass_profile_centres=True, as_subplot=False,
        units='arcsec', kpc_per_arcsec=None, figsize=(7, 7), aspect='square',
        cmap='jet', norm='linear', norm_min=None, norm_max=None, linthresh=0.05, linscale=0.01,
        cb_ticksize=10, cb_fraction=0.047, cb_pad=0.01, cb_tick_values=None, cb_tick_labels=None,
        title='Fit Model Image', titlesize=16, xlabelsize=16, ylabelsize=16, xyticksize=16,
        mask_pointsize=10, position_pointsize=10,
        output_path=None, output_format='show', output_filename='fit_model_image_of_plane'):
    """Plot the model image of a specific plane of a lens fit.

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

    Parameters
    -----------
    fit : datas.fitting.fitting.AbstractFitter
        The fit to the datas, which includes a list of every model image, residual_map, chi-squareds, etc.
    plane_indexes : [int]
        The plane from which the model image is generated.
    """

    centres = get_mass_profile_centes(plot_mass_profile_centres=plot_mass_profile_centres, fit=fit)

    if plot_foreground:

        if fit.tracer.total_planes == 2:
            model_image = fit.model_image_of_planes[0]
        else:
            model_image = sum(fit.model_image_of_planes[0:-2])

    elif plot_source:

        model_image = fit.model_image_of_planes[-1]

    else:

        raise exc.PlottingException('Both plot_foreground and plot_source were False, one must be True')

    array_plotters.plot_array(
        array=model_image, mask=mask, extract_array_from_mask=extract_array_from_mask,
        zoom_around_mask=zoom_around_mask, positions=positions, centres=centres, as_subplot=as_subplot,
        units=units, kpc_per_arcsec=kpc_per_arcsec, figsize=figsize, aspect=aspect,
        cmap=cmap, norm=norm, norm_min=norm_min, norm_max=norm_max, linthresh=linthresh, linscale=linscale,
        cb_ticksize=cb_ticksize, cb_fraction=cb_fraction, cb_pad=cb_pad,
        cb_tick_values=cb_tick_values, cb_tick_labels=cb_tick_labels,
        title=title, titlesize=titlesize, xlabelsize=xlabelsize, ylabelsize=ylabelsize, xyticksize=xyticksize,
        mask_pointsize=mask_pointsize, position_pointsize=position_pointsize,
        output_path=output_path, output_format=output_format, output_filename=output_filename)

Response: Plot the model image of a specific plane of a lens fit.


Instruction:
Explain what the following Python 3 code does
def check_tracer_for_mass_profile(func):

    @wraps(func)
    def wrapper(self):
        """

        Parameters
        ----------
        self

        Returns
        -------
            A value or coordinate in the same coordinate system as those passed in.
        """

        if self.has_mass_profile is True:
            return func(self)
        else:
            return None

    return wrapper

Response: A property decorator that checks if the tracer s galaxies have a mass profile.


Instruction:
Given the following Python 3 function, write the documentation
def convolve_mapping_matrix(self, mapping_matrix):
        return self.convolve_matrix_jit(mapping_matrix, self.image_frame_indexes,
                                        self.image_frame_psfs, self.image_frame_lengths)

Response: Given a mapping matrix convolves every entry in the given inversion mapping matrix and returns a new set of entries.


Instruction:
Write a Python 3 script for
computing the total mass within a circle in the specified units.

Response:
def mass_within_circle_in_units(self, radius: dim.Length, unit_mass='angular', kpc_per_arcsec=None,
                                    critical_surface_density=None):
        """ 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).
        """

        self.check_units_of_radius_and_critical_surface_density(
            radius=radius, critical_surface_density=critical_surface_density)

        profile = self.new_profile_with_units_converted(
            unit_length=radius.unit_length, unit_mass='angular',
            kpc_per_arcsec=kpc_per_arcsec, critical_surface_density=critical_surface_density)

        mass_angular = dim.Mass(value=quad(profile.mass_integral, a=0.0, b=radius, args=(1.0,))[0], unit_mass='angular')
        return mass_angular.convert(unit_mass=unit_mass, critical_surface_density=critical_surface_density)


Instruction:
Implement a function in Python 3 to
compute the total angular mass within an ellipse of a given major axis.

Response:
def mass_within_ellipse_in_units(self, major_axis, unit_mass='angular', kpc_per_arcsec=None,
                                     critical_surface_density=None):
        """ 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).
        """

        self.check_units_of_radius_and_critical_surface_density(
            radius=major_axis, critical_surface_density=critical_surface_density)

        profile = self.new_profile_with_units_converted(
            unit_length=major_axis.unit_length, unit_mass='angular',
            kpc_per_arcsec=kpc_per_arcsec, critical_surface_density=critical_surface_density)

        mass_angular = dim.Mass(value=quad(profile.mass_integral, a=0.0, b=major_axis, args=(self.axis_ratio,))[0],
                                unit_mass='angular')
        return mass_angular.convert(unit_mass=unit_mass, critical_surface_density=critical_surface_density)


Instruction:
Can you write a function in Python 3 where it
integrates an elliptical light profile into mass

Response:
def mass_integral(self, x, axis_ratio):
        """Routine to integrate an elliptical light profiles - set axis ratio to 1 to compute the luminosity within a \
        circle"""
        r = x * axis_ratio
        return 2 * np.pi * r * self.convergence_func(x)


Instruction:
Implement a function in Python 3 to
calculate the density between two circular annuli in angular units.

Response:
def density_between_circular_annuli_in_angular_units(self, inner_annuli_radius, outer_annuli_radius):
        """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.
        """
        annuli_area = (np.pi * outer_annuli_radius ** 2.0) - (np.pi * inner_annuli_radius ** 2.0)
        return (self.mass_within_circle_in_units(radius=outer_annuli_radius) -
                self.mass_within_circle_in_units(radius=inner_annuli_radius)) \
               / annuli_area


Instruction:
How would you explain what the following Python 3 function does
def average_convergence_of_1_radius_in_units(self, unit_length='arcsec', kpc_per_arcsec=None):

        def func(radius):
            radius = dim.Length(radius, unit_length=unit_length)
            return self.mass_within_circle_in_units(radius=radius) - np.pi * radius ** 2.0

        radius = self.ellipticity_rescale * root_scalar(func, bracket=[1e-4, 1000.0]).root
        radius = dim.Length(radius, unit_length)
        return radius.convert(unit_length=unit_length, kpc_per_arcsec=kpc_per_arcsec)

Response: The average convergence of 1 radius in units.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def einstein_radius_rescaled(self):
        return ((3 - self.slope) / (1 + self.axis_ratio)) * self.einstein_radius ** (self.slope - 1)

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


Instruction:
Write a Python 3 script to
calculate the projected convergence at a given set of arc - second gridded coordinates.

Response:
def convergence_from_grid(self, grid):
        """ 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.
        """

        surface_density_grid = np.zeros(grid.shape[0])

        grid_eta = self.grid_to_elliptical_radii(grid)

        for i in range(grid.shape[0]):
            surface_density_grid[i] = self.convergence_func(grid_eta[i])

        return surface_density_grid


Instruction:
Explain what the following Python 3 code does
def potential_from_grid(self, grid):

        potential_grid = quad_grid(self.potential_func, 0.0, 1.0, grid,
                                   args=(self.axis_ratio, self.slope, self.core_radius))[0]

        return self.einstein_radius_rescaled * self.axis_ratio * potential_grid

Response: Calculates the potential at a given set of arc - second gridded coordinates.


Instruction:
Given the following Python 3 function, write the documentation
def deflections_from_grid(self, grid):

        def calculate_deflection_component(npow, index):
            einstein_radius_rescaled = self.einstein_radius_rescaled

            deflection_grid = self.axis_ratio * grid[:, index]
            deflection_grid *= quad_grid(self.deflection_func, 0.0, 1.0,
                                         grid, args=(npow, self.axis_ratio,
                                                     einstein_radius_rescaled, self.slope,
                                                     self.core_radius))[0]

            return deflection_grid

        deflection_y = calculate_deflection_component(1.0, 0)
        deflection_x = calculate_deflection_component(0.0, 1)

        return self.rotate_grid_from_profile(np.multiply(1.0, np.vstack((deflection_y, deflection_x)).T))

Response: Calculates the deflection angles at a given set of arc - second coordinates.


Instruction:
Create a Python 3 function for
calculating the deflection angles at a given set of arc - second gridded coordinates.

Response:
def deflections_from_grid(self, grid):
        """
        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.
        """
        eta = self.grid_to_grid_radii(grid=grid)
        deflection = np.multiply(2. * self.einstein_radius_rescaled, np.divide(
            np.add(np.power(np.add(self.core_radius ** 2, np.square(eta)), (3. - self.slope) / 2.),
                   -self.core_radius ** (3 - self.slope)), np.multiply((3. - self.slope), eta)))
        return self.grid_to_grid_cartesian(grid=grid, radius=deflection)


Instruction:
How would you code a function in Python 3 to
calculate the deflection angles at a given set of arc - second coordinates.

Response:
def deflections_from_grid(self, grid):
        """
        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.
        """
        factor = 2.0 * self.einstein_radius_rescaled * self.axis_ratio / np.sqrt(1 - self.axis_ratio ** 2)

        psi = np.sqrt(np.add(np.multiply(self.axis_ratio ** 2, np.square(grid[:, 1])), np.square(grid[:, 0])))

        deflection_y = np.arctanh(np.divide(np.multiply(np.sqrt(1 - self.axis_ratio ** 2), grid[:, 0]), psi))
        deflection_x = np.arctan(np.divide(np.multiply(np.sqrt(1 - self.axis_ratio ** 2), grid[:, 1]), psi))
        return self.rotate_grid_from_profile(np.multiply(factor, np.vstack((deflection_y, deflection_x)).T))


Instruction:
Create a Python 3 function for
calculating the potential at a given set of arc - second gridded coordinates.

Response:
def potential_from_grid(self, grid):
        """
        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 = self.grid_to_elliptical_radii(grid)
        return 2.0 * self.einstein_radius_rescaled * eta


Instruction:
Here you have a function in Python 3, explain what it does
def deflections_from_grid(self, grid):
        return self.grid_to_grid_cartesian(grid=grid,
                                           radius=np.full(grid.shape[0], 2.0 * self.einstein_radius_rescaled))

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


Instruction:
Write a Python 3 function that can
tabulate an integral over the surface density of deflection potential of a mass profile.

Response:
def tabulate_integral(self, grid, tabulate_bins):
        """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.
        """
        eta_min = 1.0e-4
        eta_max = 1.05 * np.max(self.grid_to_elliptical_radii(grid))

        minimum_log_eta = np.log10(eta_min)
        maximum_log_eta = np.log10(eta_max)
        bin_size = (maximum_log_eta - minimum_log_eta) / (tabulate_bins - 1)

        return eta_min, eta_max, minimum_log_eta, maximum_log_eta, bin_size


Instruction:
Implement a function in Python 3 to
calculate the potential at a given set of arc - second coordinates.

Response:
def potential_from_grid(self, grid, tabulate_bins=1000):
        """
        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
        def deflection_integrand(x, kappa_radius, scale_radius, inner_slope):
            return (x + kappa_radius / scale_radius) ** (inner_slope - 3) * ((1 - np.sqrt(1 - x ** 2)) / x)

        eta_min, eta_max, minimum_log_eta, maximum_log_eta, bin_size = self.tabulate_integral(grid, tabulate_bins)

        potential_grid = np.zeros(grid.shape[0])

        deflection_integral = np.zeros((tabulate_bins,))

        for i in range(tabulate_bins):
            eta = 10. ** (minimum_log_eta + (i - 1) * bin_size)

            integral = \
                quad(deflection_integrand, a=0.0, b=1.0, args=(eta, self.scale_radius, self.inner_slope),
                     epsrel=EllipticalGeneralizedNFW.epsrel)[0]

            deflection_integral[i] = ((eta / self.scale_radius) ** (2 - self.inner_slope)) * (
                    (1.0 / (3 - self.inner_slope)) *
                    special.hyp2f1(3 - self.inner_slope, 3 - self.inner_slope, 4 - self.inner_slope,
                                   - (eta / self.scale_radius)) + integral)

        for i in range(grid.shape[0]):
            potential_grid[i] = (2.0 * self.kappa_s * self.axis_ratio) * \
                                quad(self.potential_func, a=0.0, b=1.0, args=(grid[i, 0], grid[i, 1],
                                                                              self.axis_ratio, minimum_log_eta,
                                                                              maximum_log_eta, tabulate_bins,
                                                                              deflection_integral),
                                     epsrel=EllipticalGeneralizedNFW.epsrel)[0]

        return potential_grid


Instruction:
Can you generate the documentation for the following Python 3 function
def deflections_from_grid(self, grid, tabulate_bins=1000):

        @jit_integrand
        def surface_density_integrand(x, kappa_radius, scale_radius, inner_slope):
            return (3 - inner_slope) * (x + kappa_radius / scale_radius) ** (inner_slope - 4) * (1 - np.sqrt(1 - x * x))

        def calculate_deflection_component(npow, index):
            deflection_grid = 2.0 * self.kappa_s * self.axis_ratio * grid[:, index]
            deflection_grid *= quad_grid(self.deflection_func, 0.0, 1.0,
                                         grid, args=(npow, self.axis_ratio, minimum_log_eta, maximum_log_eta,
                                                     tabulate_bins, surface_density_integral),
                                         epsrel=EllipticalGeneralizedNFW.epsrel)[0]

            return deflection_grid

        eta_min, eta_max, minimum_log_eta, maximum_log_eta, bin_size = self.tabulate_integral(grid, tabulate_bins)

        surface_density_integral = np.zeros((tabulate_bins,))

        for i in range(tabulate_bins):
            eta = 10. ** (minimum_log_eta + (i - 1) * bin_size)

            integral = quad(surface_density_integrand, a=0.0, b=1.0, args=(eta, self.scale_radius,
                                                                           self.inner_slope),
                            epsrel=EllipticalGeneralizedNFW.epsrel)[0]

            surface_density_integral[i] = ((eta / self.scale_radius) ** (1 - self.inner_slope)) * \
                                          (((1 + eta / self.scale_radius) ** (self.inner_slope - 3)) + integral)

        deflection_y = calculate_deflection_component(1.0, 0)
        deflection_x = calculate_deflection_component(0.0, 1)

        return self.rotate_grid_from_profile(np.multiply(1.0, np.vstack((deflection_y, deflection_x)).T))

Response: Calculates the deflection angles at a given set of arc - second coordinates.


Instruction:
Make a summary of the following Python 3 code
def deflections_from_grid(self, grid, **kwargs):

        eta = np.multiply(1. / self.scale_radius, self.grid_to_grid_radii(grid))

        deflection_grid = np.zeros(grid.shape[0])

        for i in range(grid.shape[0]):
            deflection_grid[i] = np.multiply(4. * self.kappa_s * self.scale_radius, self.deflection_func_sph(eta[i]))

        return self.grid_to_grid_cartesian(grid, deflection_grid)

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


Instruction:
Explain what the following Python 3 code does
def deflections_from_grid(self, grid, **kwargs):

        eta = np.multiply(1. / self.scale_radius, self.grid_to_grid_radii(grid))

        deflection_grid = np.multiply((4. * self.kappa_s * self.scale_radius / eta), self.deflection_func_sph(eta))

        return self.grid_to_grid_cartesian(grid, deflection_grid)

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


Instruction:
Can you generate the documentation for the following Python 3 function
def potential_from_grid(self, grid):
        potential_grid = quad_grid(self.potential_func, 0.0, 1.0, grid,
                                   args=(self.axis_ratio, self.kappa_s, self.scale_radius),
                                   epsrel=1.49e-5)[0]

        return potential_grid

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


Instruction:
Can you implement a function in Python 3 that
calculates the deflection angles at a given set of arc - second coordinates.

Response:
def deflections_from_grid(self, grid):
        """
        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.
        """

        def calculate_deflection_component(npow, index):
            deflection_grid = self.axis_ratio * grid[:, index]
            deflection_grid *= quad_grid(self.deflection_func, 0.0, 1.0, grid,
                                         args=(npow, self.axis_ratio, self.kappa_s,
                                               self.scale_radius))[0]

            return deflection_grid

        deflection_y = calculate_deflection_component(1.0, 0)
        deflection_x = calculate_deflection_component(0.0, 1)

        return self.rotate_grid_from_profile(np.multiply(1.0, np.vstack((deflection_y, deflection_x)).T))