Instruction:
How would you code a function in Python 3 to
return the 1d array of the data element that is fitted for including masking

Response:
def data_response(self):
        """
        returns the 1d array of the data element that is fitted for (including masking)

        :return: 1d numpy array
        """
        d = self.ImageNumerics.image2array(self.Data.data * self.ImageNumerics.mask)
        return d


Instruction:
Can you generate the documentation for the following Python 3 function
def error_response(self, kwargs_lens, kwargs_ps):
        model_error = self.error_map(kwargs_lens, kwargs_ps)
        error_map_1d = self.ImageNumerics.image2array(model_error)
        C_D_response = self.ImageNumerics.C_D_response + error_map_1d
        return C_D_response, model_error

Response: returns the 1d array of response and 2d array of additonal errors


Instruction:
Can you generate a brief explanation for the following Python 3 code
def reduced_chi2(self, model, error_map=0):
        chi2 = self.reduced_residuals(model, error_map)
        return np.sum(chi2**2) / self.num_data_evaluate()

Response:
returns reduced chi2
        :param model:
        :param error_map:
        :return:


Instruction:
Write a Python 3 function that can
convert keyword arguments depending on model options to tuple of parameters

Response:
def kwargs2args(self, kwargs_lens=None, kwargs_source=None, kwargs_lens_light=None, kwargs_ps=None, kwargs_cosmo=None):
        """
        inverse of getParam function
        :param kwargs_lens: keyword arguments depending on model options
        :param kwargs_source: keyword arguments depending on model options
        :return: tuple of parameters
        """

        args = self.lensParams.setParams(kwargs_lens)
        args += self.souceParams.setParams(kwargs_source)
        args += self.lensLightParams.setParams(kwargs_lens_light)
        args += self.pointSourceParams.setParams(kwargs_ps)
        args += self.cosmoParams.setParams(kwargs_cosmo)
        return args


Instruction:
Implement a Python 3 function for
mapping the image plane position definition of the source plane to the image plane position definition of the source plane

Response:
def image2source_plane(self, kwargs_source, kwargs_lens, image_plane=False):
        """
        maps the image plane position definition of the source plane

        :param kwargs_source:
        :param kwargs_lens:
        :return:
        """
        kwargs_source_copy = copy.deepcopy(kwargs_source)
        for i, kwargs in enumerate(kwargs_source_copy):
            if self._image_plane_source_list[i] is True and not image_plane:
                if 'center_x' in kwargs:
                    x_mapped, y_mapped = self._image2SourceMapping.image2source(kwargs['center_x'], kwargs['center_y'],
                                                                                kwargs_lens, idex_source=i)
                    kwargs['center_x'] = x_mapped
                    kwargs['center_y'] = y_mapped
        return kwargs_source_copy


Instruction:
Make a summary of the following Python 3 code
def update_lens_scaling(self, kwargs_cosmo, kwargs_lens, inverse=False):
        kwargs_lens_updated = copy.deepcopy(kwargs_lens)
        if self._mass_scaling is False:
            return kwargs_lens_updated
        scale_factor_list = np.array(kwargs_cosmo['scale_factor'])
        if inverse is True:
            scale_factor_list = 1. / np.array(kwargs_cosmo['scale_factor'])
        for i, kwargs in enumerate(kwargs_lens_updated):
            if self._mass_scaling_list[i] is not False:
                scale_factor = scale_factor_list[self._mass_scaling_list[i] - 1]
                if 'theta_E' in kwargs:
                    kwargs['theta_E'] *= scale_factor
                elif 'theta_Rs' in kwargs:
                    kwargs['theta_Rs'] *= scale_factor
                elif 'sigma0' in kwargs:
                    kwargs['sigma0'] *= scale_factor
                elif 'k_eff' in kwargs:
                    kwargs['k_eff'] *= scale_factor
        return kwargs_lens_updated

Response: multiplies the scaling parameters of the profiles of the lens


Instruction:
Write a Python 3 script for
testing whether the image positions map back to the same source position

Response:
def check_solver(self, kwargs_lens, kwargs_ps, kwargs_cosmo={}):
        """
        test whether the image positions map back to the same source position
        :param kwargs_lens:
        :param kwargs_ps:
        :return: Euclidean distance between the rayshooting of the image positions
        """
        if self._solver is True:
            image_x, image_y = kwargs_ps[0]['ra_image'], kwargs_ps[0]['dec_image']
            image_x, image_y = self.real_image_positions(image_x, image_y, kwargs_cosmo)
            dist = self._solver_module.check_solver(image_x, image_y, kwargs_lens)
            return np.max(dist)
        else:
            return 0


Instruction:
How would you implement a function in Python 3 that
prints the current setting of the parameter class.

Response:
def print_setting(self):
        """
        prints the setting of the parameter class

        :return:
        """
        num, param_list = self.num_param()
        num_linear = self.num_param_linear()

        print("The following model options are chosen:")
        print("Lens models:", self._lens_model_list)
        print("Source models:", self._source_light_model_list)
        print("Lens light models:", self._lens_light_model_list)
        print("Point source models:", self._point_source_model_list)
        print("===================")
        print("The following parameters are being fixed:")
        print("Lens:", self.lensParams.kwargs_fixed)
        print("Source:", self.souceParams.kwargs_fixed)
        print("Lens light:", self.lensLightParams.kwargs_fixed)
        print("Point source:", self.pointSourceParams.kwargs_fixed)
        print("===================")
        print("Joint parameters for different models")
        print("Joint lens with lens:", self._joint_lens_with_lens)
        print("Joint lens with lens light:", self._joint_lens_light_with_lens_light)
        print("Joint source with source:", self._joint_source_with_source)
        print("Joint lens with light:", self._joint_lens_with_light)
        print("Joint source with point source:", self._joint_source_with_point_source)
        print("===================")
        print("Number of non-linear parameters being sampled: ", num)
        print("Parameters being sampled: ", param_list)
        print("Number of linear parameters being solved for: ", num_linear)


Instruction:
Given the following Python 3 function, write the documentation
def derivatives(self, x, y, Rs, theta_Rs, r_core, center_x=0, center_y=0):

        rho0 = self._alpha2rho0(theta_Rs=theta_Rs, Rs=Rs, r_core=r_core)

        if Rs < 0.0000001:
            Rs = 0.0000001
        x_ = x - center_x
        y_ = y - center_y
        R = np.sqrt(x_ ** 2 + y_ ** 2)

        dx, dy = self.coreBurkAlpha(R, Rs, rho0, r_core, x_, y_)

        return dx, dy

Response: returns the derivative of the core Burk at the given coordinates


Instruction:
Can you generate a brief explanation for the following Python 3 code
def hessian(self, x, y, Rs, theta_Rs, r_core, center_x=0, center_y=0):

        """
        :param x: x coordinate
        :param y: y coordinate
        :param Rs: scale radius
        :param rho0: central core density
        :param r_core: core radius
        :param center_x:
        :param center_y:
        :return:
        """

        if Rs < 0.0001:
            Rs = 0.0001
        x_ = x - center_x
        y_ = y - center_y
        R = np.sqrt(x_ ** 2 + y_ ** 2)

        rho0 = self._alpha2rho0(theta_Rs=theta_Rs, Rs=Rs, r_core=r_core)

        kappa = self.density_2d(x_, y_, Rs, rho0, r_core)

        gamma1, gamma2 = self.cBurkGamma(R, Rs, rho0, r_core, x_, y_)
        f_xx = kappa + gamma1
        f_yy = kappa - gamma1
        f_xy = gamma2
        return f_xx, f_yy, f_xy

Response: calculate the hessian of a set of attributes


Instruction:
How would you code a function in Python 3 to
calculate mass of a 2D system from a distance and radius

Response:
def mass_2d(self, R, Rs, rho0, r_core):

        """
        analytic solution of the projection integral
        (convergence)

        :param R: projected distance
        :param Rs: scale radius
        :param rho0: central core density
        :param r_core: core radius
        """

        x = R * Rs ** -1
        p = Rs * r_core ** -1
        gx = self._G(x, p)

        m_2d = 2 * np.pi * rho0 * Rs ** 3 * gx

        return m_2d


Instruction:
Make a summary of the following Python 3 code
def coreBurkAlpha(self, R, Rs, rho0, r_core, ax_x, ax_y):
        x = R * Rs ** -1
        p = Rs * r_core ** -1

        gx = self._G(x, p)

        a = 2 * rho0 * Rs ** 2 * gx / x

        return a * ax_x / R, a * ax_y / R

Response: calculate core burk alpha


Instruction:
Can you write a function in Python 3 where it
calculates 3D mass of a set of species

Response:
def mass_3d(self, R, Rs, rho0, r_core):
        """
        :param R: projected distance
        :param Rs: scale radius
        :param rho0: central core density
        :param r_core: core radius
        """

        Rs = float(Rs)
        b = r_core * Rs ** -1
        c = R * Rs ** -1

        M0 = 4*np.pi*Rs**3 * rho0

        return M0 * (1+b**2) ** -1 * (0.5*np.log(1+c**2) + b**2*np.log(c*b**-1 + 1) - b*np.arctan(c))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def cBurkPot(self, R, Rs, rho0, r_core):

        """
        :param R: projected distance
        :param Rs: scale radius
        :param rho0: central core density
        :param r_core: core radius
        """
        x = R * Rs ** -1
        p = Rs * r_core ** -1
        hx = self._H(x, p)

        return 2 * rho0 * Rs ** 3 * hx

Response:
:param R: projected distance
        :param Rs: scale radius
        :param rho0: central core density
        :param r_core: core radius


Instruction:
Make a summary of the following Python 3 code
def linear_response_matrix(self, kwargs_lens=None, kwargs_source=None, kwargs_lens_light=None, kwargs_ps=None):
        A = []
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                A_i = self._imageModel_list[i].linear_response_matrix(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps)
                if A == []:
                    A = A_i
                else:
                    A = np.append(A, A_i, axis=1)
        return A

Response: compute the linear response matrix for the image model


Instruction:
Explain what the following Python 3 code does
def data_response(self):
        d = []
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                d_i = self._imageModel_list[i].data_response
                if d == []:
                    d = d_i
                else:
                    d = np.append(d, d_i)
        return d

Response: returns the 1d numpy array of the data element that is fitted for ( including masking


Instruction:
Create a Python 3 function to
map 1d vector of joint exposures in list of 2d images of single exposures in list of 2d images of single exposures

Response:
def _array2image_list(self, array):
        """
        maps 1d vector of joint exposures in list of 2d images of single exposures

        :param array: 1d numpy array
        :return: list of 2d numpy arrays of size  of exposures
        """
        image_list = []
        k = 0
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                num_data = self.num_response_list[i]
                array_i = array[k:k + num_data]
                image_i = self._imageModel_list[i].ImageNumerics.array2image(array_i)
                image_list.append(image_i)
                k += num_data
        return image_list


Instruction:
Given the following Python 3 function, write the documentation
def likelihood_data_given_model(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, source_marg=False):
        # generate image
        im_sim_list, model_error_list, cov_matrix, param = self.image_linear_solve(kwargs_lens, kwargs_source,
                                                                         kwargs_lens_light, kwargs_ps,
                                                                         inv_bool=source_marg)
        # compute X^2
        logL = 0
        index = 0
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                logL += self._imageModel_list[i].Data.log_likelihood(im_sim_list[index], self._imageModel_list[i].ImageNumerics.mask, model_error_list[index])
                index += 1
        if cov_matrix is not None and source_marg:
            marg_const = de_lens.marginalisation_const(cov_matrix)
            logL += marg_const
        return logL

Response: computes the likelihood of the data given a model


Instruction:
Write a Python 3 function that can
compute the image (lens and source surface brightness with a given lens model). The linear parameters are computed with a weighted linear least square optimization (i.e. flux normalization of the brightness profiles) :param kwargs_lens: list of keyword arguments corresponding to the superposition of different lens profiles :param kwargs_source: list of keyword arguments corresponding to the superposition of different source light profiles :param kwargs_lens_light: list of keyword arguments corresponding to different lens light surface brightness profiles :param kwargs_ps: keyword arguments corresponding to "other" parameters, such as external shear and point source image positions :param inv_bool: if True, invert the full linear solver Matrix Ax = y for the purpose of the covariance matrix. :return: 1d array of surface brightness pixels of the optimal solution of the linear parameters to match the data

Response:
def image_linear_solve(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, inv_bool=False):
        """
        computes the image (lens and source surface brightness with a given lens model).
        The linear parameters are computed with a weighted linear least square optimization (i.e. flux normalization of the brightness profiles)
        :param kwargs_lens: list of keyword arguments corresponding to the superposition of different lens profiles
        :param kwargs_source: list of keyword arguments corresponding to the superposition of different source light profiles
        :param kwargs_lens_light: list of keyword arguments corresponding to different lens light surface brightness profiles
        :param kwargs_ps: keyword arguments corresponding to "other" parameters, such as external shear and point source image positions
        :param inv_bool: if True, invert the full linear solver Matrix Ax = y for the purpose of the covariance matrix.
        :return: 1d array of surface brightness pixels of the optimal solution of the linear parameters to match the data
        """
        wls_list, error_map_list, cov_param_list, param_list = [], [], [], []
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                kwargs_source_i = [kwargs_source[k] for k in self._index_source_list[i]]
                kwargs_lens_light_i = [kwargs_lens_light[k] for k in self._index_lens_light_list[i]]
                wls_model, error_map, cov_param, param = self._imageModel_list[i].image_linear_solve(kwargs_lens,
                                                                                kwargs_source_i,
                                                                                kwargs_lens_light_i,
                                                                                kwargs_ps,
                                                                                inv_bool=inv_bool)
                wls_list.append(wls_model)
                error_map_list.append(error_map)
                cov_param_list.append(cov_param)
                param_list.append(param)
        return wls_list, error_map_list, cov_param_list, param_list


Instruction:
Explain what the following Python 3 code does
def likelihood_data_given_model(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, source_marg=False):
        # generate image
        logL = 0
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                kwargs_source_i = [kwargs_source[k] for k in self._index_source_list[i]]
                kwargs_lens_light_i = [kwargs_lens_light[k] for k in self._index_lens_light_list[i]]
                logL += self._imageModel_list[i].likelihood_data_given_model(kwargs_lens, kwargs_source_i,
                                                                             kwargs_lens_light_i, kwargs_ps,
                                                                             source_marg=source_marg)
        return logL

Response: computes the likelihood of the data given a model


Instruction:
Make a summary of the following Python 3 code
def check_solver(self, image_x, image_y, kwargs_lens):
        source_x, source_y = self._lensModel.ray_shooting(image_x, image_y, kwargs_lens)
        dist = np.sqrt((source_x - source_x[0]) ** 2 + (source_y - source_y[0]) ** 2)
        return dist

Response: returns the precision of the solver to match the image position


Instruction:
Write a Python 3 function for
adding fixed lens to kwargs that are kept fixed during run depending on options

Response:
def add_fixed_lens(self, kwargs_fixed_lens, kwargs_lens_init):
        """
        returns kwargs that are kept fixed during run, depending on options
        :param kwargs_options:
        :param kwargs_lens:
        :return:
        """
        kwargs_fixed_lens = self._solver.add_fixed_lens(kwargs_fixed_lens, kwargs_lens_init)
        return kwargs_fixed_lens


Instruction:
Can you generate the documentation for the following Python 3 function
def epsilon_crit(self):
        if not hasattr(self, '_Epsilon_Crit'):
            const_SI = const.c ** 2 / (4 * np.pi * const.G)  #c^2/(4*pi*G) in units of [kg/m]
            conversion = const.Mpc / const.M_sun  # converts [kg/m] to [M_sun/Mpc]
            factor = const_SI*conversion   #c^2/(4*pi*G) in units of [M_sun/Mpc]
            self._Epsilon_Crit = self.D_s/(self.D_d*self.D_ds) * factor #[M_sun/Mpc^2]
        return self._Epsilon_Crit

Response: returns the critical projected mass density in units of M_sun Mpc^2


Instruction:
Can you write a function in Python 3 where it
gets the mass of the object in the given Einstein radius

Response:
def mass_in_theta_E(self, theta_E):
        """
        mass within Einstein radius (area * epsilon crit) [M_sun]
        :param theta_E: Einstein radius [arcsec]
        :return: mass within Einstein radius [M_sun]
        """
        mass = self.arcsec2phys_lens(theta_E) ** 2 * np.pi * self.epsilon_crit
        return mass


Instruction:
Can you generate a brief explanation for the following Python 3 code
def nfw_angle2physical(self, Rs_angle, theta_Rs):
        Rs = Rs_angle * const.arcsec * self.D_d
        theta_scaled = theta_Rs * self.epsilon_crit * self.D_d * const.arcsec
        rho0 = theta_scaled / (4 * Rs ** 2 * (1 + np.log(1. / 2.)))
        rho0_com = rho0 / self.h**2 * self.a_z(self.z_lens)**3
        c = self.nfw_param.c_rho0(rho0_com)
        r200 = c * Rs
        M200 = self.nfw_param.M_r200(r200 * self.h / self.a_z(self.z_lens)) / self.h
        return rho0, Rs, c, r200, M200

Response: converts the angular parameters into the physical ones for an NFW profile


Instruction:
How would you explain what the following Python 3 function does
def nfw_physical2angle(self, M, c):
        rho0, Rs, r200 = self.nfwParam_physical(M, c)
        Rs_angle = Rs / self.D_d / const.arcsec  # Rs in arcsec
        theta_Rs = rho0 * (4 * Rs ** 2 * (1 + np.log(1. / 2.)))
        return Rs_angle,  theta_Rs / self.epsilon_crit / self.D_d / const.arcsec

Response: converts the physical mass and concentration parameter of an NFW profile into the lensing quantities


Instruction:
Make a summary of the following Python 3 code
def nfwParam_physical(self, M, c):
        r200 = self.nfw_param.r200_M(M * self.h) / self.h * self.a_z(self.z_lens)  # physical radius r200
        rho0 = self.nfw_param.rho0_c(c) * self.h**2 / self.a_z(self.z_lens)**3 # physical density in M_sun/Mpc**3
        Rs = r200/c
        return rho0, Rs, r200

Response: returns the NFW parameters in physical units


Instruction:
How would you implement a function in Python 3 that
converts the lensing Einstein radius into a physical velocity dispersion in units

Response:
def sis_theta_E2sigma_v(self, theta_E):
        """
        converts the lensing Einstein radius into a physical velocity dispersion
        :param theta_E: Einstein radius (in arcsec)
        :return: velocity dispersion in units (km/s)
        """
        v_sigma_c2 = theta_E * const.arcsec / (4*np.pi) * self.D_s / self.D_ds
        return np.sqrt(v_sigma_c2)*const.c / 1000


Instruction:
Create a Python 3 function to
convert the velocity dispersion into an Einstein radius for a SIS profile

Response:
def sis_sigma_v2theta_E(self, v_sigma):
        """
        converts the velocity dispersion into an Einstein radius for a SIS profile
        :param v_sigma: velocity dispersion (km/s)
        :return: theta_E (arcsec)
        """
        theta_E = 4 * np.pi * (v_sigma * 1000./const.c)**2 * self.D_ds / self.D_s / const.arcsec
        return theta_E


Instruction:
Write a Python 3 function that can
get the angular diameter of the class

Response:
def D_d(self, H_0, Om0, Ode0=None):
        """
        angular diameter to deflector
        :param H_0: Hubble parameter [km/s/Mpc]
        :param Om0: normalized matter density at present time
        :return: float [Mpc]
        """
        lensCosmo = self._get_cosom(H_0, Om0, Ode0)
        return lensCosmo.D_d


Instruction:
Here you have a function in Python 3, explain what it does
def D_s(self, H_0, Om0, Ode0=None):
        lensCosmo = self._get_cosom(H_0, Om0, Ode0)
        return lensCosmo.D_s

Response: get the angular diameter of source timecluster


Instruction:
How would you implement a function in Python 3 that
gets the angular diameter from deflector to source

Response:
def D_ds(self, H_0, Om0, Ode0=None):
        """
        angular diameter from deflector to source
        :param H_0: Hubble parameter [km/s/Mpc]
        :param Om0: normalized matter density at present time
        :return: float [Mpc]
        """
        lensCosmo = self._get_cosom(H_0, Om0, Ode0)
        return lensCosmo.D_ds


Instruction:
Implement a function in Python 3 to
get the time delay distance between the base and the lens cosmology

Response:
def D_dt(self, H_0, Om0, Ode0=None):
        """
        time delay distance
        :param H_0: Hubble parameter [km/s/Mpc]
        :param Om0: normalized matter density at present time
        :return: float [Mpc]
        """
        lensCosmo = self._get_cosom(H_0, Om0, Ode0)
        return lensCosmo.D_dt


Instruction:
Create a Python 3 function to
return df dx dy of the function

Response:
def derivatives(self, x, y, coeffs, beta, center_x=0, center_y=0):
        """
        returns df/dx and df/dy of the function
        """
        shapelets = self._createShapelet(coeffs)
        n_order = self._get_num_n(len(coeffs))
        dx_shapelets = self._dx_shapelets(shapelets, beta)
        dy_shapelets = self._dy_shapelets(shapelets, beta)
        n = len(np.atleast_1d(x))
        if n <= 1:
            f_x = self._shapeletOutput(x, y, beta, dx_shapelets, precalc=False)
            f_y = self._shapeletOutput(x, y, beta, dy_shapelets, precalc=False)
        else:
            H_x, H_y = self.pre_calc(x, y, beta, n_order+1, center_x, center_y)
            f_x = self._shapeletOutput(H_x, H_y, beta, dx_shapelets)
            f_y = self._shapeletOutput(H_x, H_y, beta, dy_shapelets)
        return f_x, f_y


Instruction:
Here you have a function in Python 3, explain what it does
def hessian(self, x, y, coeffs, beta, center_x=0, center_y=0):
        shapelets = self._createShapelet(coeffs)
        n_order = self._get_num_n(len(coeffs))
        dxx_shapelets = self._dxx_shapelets(shapelets, beta)
        dyy_shapelets = self._dyy_shapelets(shapelets, beta)
        dxy_shapelets = self._dxy_shapelets(shapelets, beta)
        n = len(np.atleast_1d(x))
        if n <= 1:
            f_xx = self._shapeletOutput(x, y, beta, dxx_shapelets, precalc=False)
            f_yy = self._shapeletOutput(x, y, beta, dyy_shapelets, precalc=False)
            f_xy = self._shapeletOutput(x, y, beta, dxy_shapelets, precalc=False)
        else:
            H_x, H_y = self.pre_calc(x, y, beta, n_order+2, center_x, center_y)
            f_xx = self._shapeletOutput(H_x, H_y, beta, dxx_shapelets)
            f_yy = self._shapeletOutput(H_x, H_y, beta, dyy_shapelets)
            f_xy = self._shapeletOutput(H_x, H_y, beta, dxy_shapelets)
        return f_xx, f_yy, f_xy

Response: returns Hessian matrix of function d^2f / dx^2 dy^2


Instruction:
Can you implement a function in Python 3 that
creates a shapelet array out of the coefficients a and b.

Response:
def _createShapelet(self, coeffs):
        """
        returns a shapelet array out of the coefficients *a, up to order l

        :param num_l: order of shapelets
        :type num_l: int.
        :param coeff: shapelet coefficients
        :type coeff: floats
        :returns:  complex array
        :raises: AttributeError, KeyError
        """
        n_coeffs = len(coeffs)
        num_n = self._get_num_n(n_coeffs)
        shapelets=np.zeros((num_n+1, num_n+1))
        n = 0
        k = 0
        for coeff in coeffs:
            shapelets[n-k][k] = coeff
            k += 1
            if k == n + 1:
                n += 1
                k = 0
        return shapelets


Instruction:
Can you implement a function in Python 3 that
returns the the numerical values of a set of shapelets at polar coordinates :param shapelets: set of shapelets [l=,r=,a_lr=] :type shapelets: array of size (n,3) :param coordPolar: set of coordinates in polar units :type coordPolar: array of size (n,2) :returns: array of same size with coords [r,phi] :raises: AttributeError, KeyError

Response:
def _shapeletOutput(self, x, y, beta, shapelets, precalc=True):
        """
        returns the the numerical values of a set of shapelets at polar coordinates
        :param shapelets: set of shapelets [l=,r=,a_lr=]
        :type shapelets: array of size (n,3)
        :param coordPolar: set of coordinates in polar units
        :type coordPolar: array of size (n,2)
        :returns:  array of same size with coords [r,phi]
        :raises: AttributeError, KeyError
        """
        n = len(np.atleast_1d(x))
        if n <= 1:
            values = 0.
        else:
            values = np.zeros(len(x[0]))
        n = 0
        k = 0
        i = 0
        num_n = len(shapelets)
        while i < num_n * (num_n+1)/2:
            values += self._function(x, y, shapelets[n-k][k], beta, n-k, k, precalc=precalc)
            k += 1
            if k == n + 1:
                n += 1
                k = 0
            i += 1
        return values


Instruction:
Explain what the following Python 3 code does
def _dx_shapelets(self, shapelets, beta):
        num_n = len(shapelets)
        dx = np.zeros((num_n+1, num_n+1))
        for n1 in range(num_n):
            for n2 in range(num_n):
                amp = shapelets[n1][n2]
                dx[n1+1][n2] -= np.sqrt((n1+1)/2.) * amp
                if n1 > 0:
                    dx[n1-1][n2] += np.sqrt(n1/2.) * amp
        return dx/beta

Response: Compute the derivative d / dx of the shapelets


Instruction:
Create a Python 3 function for
computing the derivative d / dx of the shapelets

Response:
def _dy_shapelets(self, shapelets, beta):
        """
        computes the derivative d/dx of the shapelet coeffs
        :param shapelets:
        :param beta:
        :return:
        """
        num_n = len(shapelets)
        dy = np.zeros((num_n+1, num_n+1))
        for n1 in range(num_n):
            for n2 in range(num_n):
                amp = shapelets[n1][n2]
                dy[n1][n2+1] -= np.sqrt((n2+1)/2.) * amp
                if n2 > 0:
                    dy[n1][n2-1] += np.sqrt(n2/2.) * amp
        return dy/beta


Instruction:
Can you generate a brief explanation for the following Python 3 code
def H_n(self, n, x):
        n_array = np.zeros(n+1)
        n_array[n] = 1
        return hermite.hermval(x, n_array, tensor=False)

Response: Returns the Hermite polynomial of order n at position x


Instruction:
Implement a function in Python 3 to
return the 1 - dimenional basis function for the given n - dimensional array and x - dimensional array.

Response:
def phi_n(self,n,x):
        """
        constructs the 1-dim basis function (formula (1) in Refregier et al. 2001)

        :param n: The n'the basis function.
        :type name: int.
        :param x: 1-dim position (dimensionless)
        :type state: float or numpy array.
        :returns:  array-- phi_n(x).
        :raises: AttributeError, KeyError
        """
        prefactor = 1./np.sqrt(2**n*np.sqrt(np.pi)*math.factorial(n))
        return prefactor*self.H_n(n,x)*np.exp(-x**2/2.)


Instruction:
How would you code a function in Python 3 to
extract the array of parameters from kwargs_list

Response:
def _extract_array(self, kwargs_list):
        """
        inverse of _update_kwargs
        :param kwargs_list:
        :return:
        """
        lens_model = self._lens_mode_list[0]
        if self._solver_type == 'CENTER':
            center_x = kwargs_list[0]['center_x']
            center_y = kwargs_list[0]['center_y']
            x = [center_x, center_y]
        elif self._solver_type == 'ELLIPSE':
            e1 = kwargs_list[0]['e1']
            e2 = kwargs_list[0]['e2']
            x = [e1, e2]
        elif self._solver_type == 'SHAPELETS':
            coeffs = list(kwargs_list[0]['coeffs'])
            [c10, c01] = coeffs[1: 3]
            x = [c10, c01]
        elif self._solver_type == 'THETA_E_PHI':
            theta_E = kwargs_list[0]['theta_E']
            e1 = kwargs_list[1]['e1']
            e2 = kwargs_list[1]['e2']
            phi_ext, gamma_ext = param_util.ellipticity2phi_gamma(e1, e2)
            x = [theta_E, phi_ext]
        else:
            raise ValueError("Solver type %s not supported for 2-point solver!" % self._solver_type)
        return x


Instruction:
Implement a function in Python 3 to
return the scaled effective exposure time of IID counts.

Response:
def scaled_exposure_time(self):
        """
        scaled "effective" exposure time of IID counts. This can be used by lenstronomy to estimate the Poisson errors
        keeping the assumption that the counts are IIDs (even if they are not).

        :return: scaled exposure time
        """
        if self._data_count_unit == 'ADU':
            exp_time = self.ccd_gain * self.exposure_time
        else:
            exp_time = self.exposure_time
        return exp_time


Instruction:
Write a Python 3 script for
converting an apparent magnitude to counts per second

Response:
def magnitude2cps(self, magnitude):
        """
        converts an apparent magnitude to counts per second (in units of the data)

        The zero point of an instrument, by definition, is the magnitude of an object that produces one count
        (or data number, DN) per second. The magnitude of an arbitrary object producing DN counts in an observation of
        length EXPTIME is therefore:
        m = -2.5 x log10(DN / EXPTIME) + ZEROPOINT

        :param magnitude: magnitude of object
        :return: counts per second of object
        """
        # compute counts in units of ADS (as magnitude zero point is defined)
        cps = data_util.magnitude2cps(magnitude, magnitude_zero_point=self._magnitude_zero_point)
        if self._data_count_unit == 'e-':
            cps *= self.ccd_gain
        return cps


Instruction:
Write a Python 3 function for
computing the density of the n - tuple

Response:
def density(self, r, rho0, Ra, Rs):
        """
        computes the density
        :param x:
        :param y:
        :param rho0:
        :param Ra:
        :param Rs:
        :return:
        """
        Ra, Rs = self._sort_ra_rs(Ra, Rs)
        rho = rho0 / ((1 + (r / Ra) ** 2) * (1 + (r / Rs) ** 2))
        return rho


Instruction:
Implement a Python 3 function for
projecting density of a 2D resource set

Response:
def density_2d(self, x, y, rho0, Ra, Rs, center_x=0, center_y=0):
        """
        projected density
        :param x:
        :param y:
        :param rho0:
        :param Ra:
        :param Rs:
        :param center_x:
        :param center_y:
        :return:
        """
        Ra, Rs = self._sort_ra_rs(Ra, Rs)
        x_ = x - center_x
        y_ = y - center_y
        r = np.sqrt(x_**2 + y_**2)
        sigma0 = self.rho2sigma(rho0, Ra, Rs)
        sigma = sigma0 * Ra * Rs / (Rs - Ra) * (1 / np.sqrt(Ra ** 2 + r ** 2) - 1 / np.sqrt(Rs ** 2 + r ** 2))
        return sigma


Instruction:
Can you write a function in Python 3 where it
calculates the mass of a 3d sphere or radius r

Response:
def mass_3d(self, r, rho0, Ra, Rs):
        """
        mass enclosed a 3d sphere or radius r
        :param r:
        :param Ra:
        :param Rs:
        :return:
        """
        m_3d = 4 * np.pi * rho0 * Ra ** 2 * Rs ** 2 / (Rs ** 2 - Ra ** 2) * (Rs * np.arctan(r / Rs) - Ra * np.arctan(r / Ra))
        return m_3d


Instruction:
How would you explain what the following Python 3 function does
def mass_2d(self, r, rho0, Ra, Rs):
        Ra, Rs = self._sort_ra_rs(Ra, Rs)
        sigma0 = self.rho2sigma(rho0, Ra, Rs)
        m_2d = 2 * np.pi * sigma0 * Ra * Rs / (Rs - Ra) * (np.sqrt(Ra ** 2 + r ** 2) - Ra - np.sqrt(Rs ** 2 + r ** 2) + Rs)
        return m_2d

Response: return the mass of the 2d sphere of radius r


Instruction:
Create a Python 3 function to
calculate total mass within the profile

Response:
def mass_tot(self, rho0, Ra, Rs):
        """
        total mass within the profile
        :param rho0:
        :param Ra:
        :param Rs:
        :return:
        """
        Ra, Rs = self._sort_ra_rs(Ra, Rs)
        sigma0 = self.rho2sigma(rho0, Ra, Rs)
        m_tot = 2 * np.pi * sigma0 * Ra * Rs
        return m_tot


Instruction:
Here you have a function in Python 3, explain what it does
def _f_A20(self, r_a, r_s):
        return r_a/(1+np.sqrt(1 + r_a**2)) - r_s/(1+np.sqrt(1 + r_s**2))

Response: Equation A20 in Eliasdottir 2004.


Instruction:
Write a Python 3 function for
converting 3d density into 2d projected density

Response:
def rho2sigma(self, rho0, Ra, Rs):
        """
        converts 3d density into 2d projected density parameter
        :param rho0:
        :param Ra:
        :param Rs:
        :return:
        """
        return np.pi * rho0 * Ra * Rs / (Rs + Ra)


Instruction:
Write a Python 3 function for
performing sqrt scaling of the input numpy array.

Response:
def sqrt(inputArray, scale_min=None, scale_max=None):
    """Performs sqrt scaling of the input numpy array.

    @type inputArray: numpy array
    @param inputArray: image data array
    @type scale_min: float
    @param scale_min: minimum data value
    @type scale_max: float
    @param scale_max: maximum data value
    @rtype: numpy array
    @return: image data array

    """

    imageData = np.array(inputArray, copy=True)

    if scale_min is None:
        scale_min = imageData.min()
    if scale_max is None:
        scale_max = imageData.max()

    imageData = imageData.clip(min=scale_min, max=scale_max)
    imageData = imageData - scale_min
    indices = np.where(imageData < 0)
    imageData[indices] = 0.0
    imageData = np.sqrt(imageData)
    imageData = imageData / math.sqrt(scale_max - scale_min)

    return imageData


Instruction:
Can you write a function in Python 3 where it
computes the log likelihood of a MCMC or PSO chain

Response:
def logL(self, args):
        """
        routine to compute X2 given variable parameters for a MCMC/PSO chain
        """
        #extract parameters
        kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, kwargs_cosmo = self.param.args2kwargs(args)
        #generate image and computes likelihood
        self._reset_point_source_cache(bool=True)
        logL = 0
        if self._check_bounds is True:
            penalty, bound_hit = self.check_bounds(args, self._lower_limit, self._upper_limit)
            logL -= penalty
            if bound_hit:
                return logL, None
        if self._image_likelihood is True:
            logL += self.image_likelihood.logL(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps)
        if self._time_delay_likelihood is True:
            logL += self.time_delay_likelihood.logL(kwargs_lens, kwargs_ps, kwargs_cosmo)
        if self._check_positive_flux is True:
            bool = self.param.check_positive_flux(kwargs_source, kwargs_lens_light, kwargs_ps)
            if bool is False:
                logL -= 10**10
        if self._flux_ratio_likelihood is True:
            logL += self.flux_ratio_likelihood.logL(kwargs_lens, kwargs_ps, kwargs_cosmo)
        logL += self._position_likelihood.logL(kwargs_lens, kwargs_ps, kwargs_cosmo)
        logL += self._prior_likelihood.logL(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, kwargs_cosmo)
        self._reset_point_source_cache(bool=False)
        return logL, None


Instruction:
Can you write a function in Python 3 where it
checks whether the parameter vector has left its bound and adds a big number if so.

Response:
def check_bounds(args, lowerLimit, upperLimit):
        """
        checks whether the parameter vector has left its bound, if so, adds a big number
        """
        penalty = 0
        bound_hit = False
        for i in range(0, len(args)):
            if args[i] < lowerLimit[i] or args[i] > upperLimit[i]:
                penalty = 10**15
                bound_hit = True
        return penalty, bound_hit


Instruction:
Create a Python 3 function for
returning the effective number of data points considered in the X2 estimation to compute the reduced X2 value

Response:
def effectiv_num_data_points(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps):
        """
        returns the effective number of data points considered in the X2 estimation to compute the reduced X2 value
        """
        num_linear = 0
        if self._image_likelihood is True:
            num_linear = self.image_likelihood.num_param_linear(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps)
        num_param, _ = self.param.num_param()
        return self.num_data - num_param - num_linear


Instruction:
Here you have a function in Python 3, explain what it does
def image2source(self, x, y, kwargs_lens, idex_source):
        if self._multi_source_plane is False:
            x_source, y_source = self._lensModel.ray_shooting(x, y, kwargs_lens)
        else:
            if self._multi_lens_plane is False:
                x_alpha, y_alpha = self._lensModel.alpha(x, y, kwargs_lens)
                scale_factor = self._deflection_scaling_list[idex_source]
                x_source = x - x_alpha * scale_factor
                y_source = y - y_alpha * scale_factor
            else:
                z_stop = self._source_redshift_list[idex_source]
                x_comov, y_comov, alpha_x, alpha_y = self._lensModel.lens_model.ray_shooting_partial(0, 0, x, y,
                                                                                0, z_stop,
                                                                                kwargs_lens,
                                                                                keep_range=False,
                                                                                include_z_start=False)

                T_z = self._bkg_cosmo.T_xy(0, z_stop)
                x_source = x_comov / T_z
                y_source = y_comov / T_z
        return x_source, y_source

Response: This function maps an image plane to the source plane coordinate.


Instruction:
Implement a function in Python 3 to
return Hessian matrix of function f_xx y_xx f_yy f_xy

Response:
def hessian(self, x, y, amp, sigma, e1, e2, center_x=0, center_y=0):
        """
        returns Hessian matrix of function d^2f/dx^2, d^f/dy^2, d^2/dxdy
        """
        alpha_ra, alpha_dec = self.derivatives(x, y, amp, sigma, e1, e2, center_x, center_y)
        diff = self._diff
        alpha_ra_dx, alpha_dec_dx = self.derivatives(x + diff, y, amp, sigma, e1, e2, center_x, center_y)
        alpha_ra_dy, alpha_dec_dy = self.derivatives(x, y + diff, amp, sigma, e1, e2, center_x, center_y)

        f_xx = (alpha_ra_dx - alpha_ra) / diff
        f_xy = (alpha_ra_dy - alpha_ra) / diff
        # f_yx = (alpha_dec_dx - alpha_dec)/diff
        f_yy = (alpha_dec_dy - alpha_dec) / diff
        return f_xx, f_yy, f_xy


Instruction:
How would you implement a function in Python 3 that
calculates the average LOS velocity dispersion in the slit

Response:
def vel_disp(self, kwargs_profile, kwargs_aperture, kwargs_light, kwargs_anisotropy, num=1000):
        """
        computes the averaged LOS velocity dispersion in the slit (convolved)
        :param gamma:
        :param phi_E:
        :param r_eff:
        :param r_ani:
        :param R_slit:
        :param FWHM:
        :return:
        """
        sigma_s2_sum = 0
        for i in range(0, num):
            sigma_s2_draw = self._vel_disp_one(kwargs_profile, kwargs_aperture, kwargs_light, kwargs_anisotropy)
            sigma_s2_sum += sigma_s2_draw
        sigma_s2_average = sigma_s2_sum/num
        return np.sqrt(sigma_s2_average)


Instruction:
Can you tell what is the following Python 3 function doing
def _vel_disp_one(self, kwargs_profile, kwargs_aperture, kwargs_light, kwargs_anisotropy):

        while True:
            r = self.lightProfile.draw_light(kwargs_light)  # draw r
            R, x, y = util.R_r(r)  # draw projected R
            x_, y_ = util.displace_PSF(x, y, self.FWHM)  # displace via PSF
            bool = self.aperture.aperture_select(x_, y_, kwargs_aperture)
            if bool is True:
                break
        sigma_s2 = self.sigma_s2(r, R, kwargs_profile, kwargs_anisotropy, kwargs_light)
        return sigma_s2

Response: Compute one realisation of the velocity dispersion realized in the slit.


Instruction:
Make a summary of the following Python 3 code
def sigma_s2(self, r, R, kwargs_profile, kwargs_anisotropy, kwargs_light):
        beta = self.anisotropy.beta_r(r, kwargs_anisotropy)
        return (1 - beta * R**2/r**2) * self.sigma_r2(r, kwargs_profile, kwargs_anisotropy, kwargs_light)

Response:
projected velocity dispersion
        :param r:
        :param R:
        :param r_ani:
        :param a:
        :param gamma:
        :param phi_E:
        :return:


Instruction:
Write a Python 3 function for
computing the radial velocity dispersion at radius r

Response:
def sigma_r2(self, r, kwargs_profile, kwargs_anisotropy, kwargs_light):
        """
        computes radial velocity dispersion at radius r (solving the Jeans equation
        :param r:
        :return:
        """
        return self.jeans_solver.sigma_r2(r, kwargs_profile, kwargs_anisotropy, kwargs_light)


Instruction:
Write a Python 3 function for
solving radial Jeans equation

Response:
def sigma_r2(self, r, kwargs_profile, kwargs_anisotropy, kwargs_light):
        """
        solves radial Jeans equation
        """
        if self._mass_profile == 'power_law':
            if self._anisotropy_type == 'r_ani':
                if self._light_profile == 'Hernquist':
                    sigma_r = self.power_law_anisotropy(r, kwargs_profile, kwargs_anisotropy, kwargs_light)
                else:
                    raise ValueError('light profile %s not supported for Jeans solver' % self._light_profile)
            else:
                raise ValueError('anisotropy type %s not implemented in Jeans equation modelling' % self._anisotropy_type)
        else:
            raise ValueError('mass profile type %s not implemented in Jeans solver' % self._mass_profile)
        return sigma_r


Instruction:
Can you create a Python 3 function that
returns a bool list if the coordinate is within the aperture ( list

Response:
def aperture_select(self, ra, dec, kwargs_aperture):
        """
        returns a bool list if the coordinate is within the aperture (list)
        :param ra:
        :param dec:
        :return:
        """
        if self._aperture_type == 'shell':
            bool_list = self.shell_select(ra, dec, **kwargs_aperture)
        elif self._aperture_type == 'slit':
            bool_list = self.slit_select(ra, dec, **kwargs_aperture)
        else:
            raise ValueError("aperture type %s not implemented!" % self._aperture_type)
        return bool_list


Instruction:
Implement a function in Python 3 to
compute the image (lens and source surface brightness with a given lens model). The linear parameters are computed with a weighted linear least square optimization (i.e. flux normalization of the brightness profiles) :param kwargs_lens: list of keyword arguments corresponding to the superposition of different lens profiles :param kwargs_source: list of keyword arguments corresponding to the superposition of different source light profiles :param kwargs_lens_light: list of keyword arguments corresponding to different lens light surface brightness profiles :param kwargs_else: keyword arguments corresponding to "other" parameters, such as external shear and point source image positions :param inv_bool: if True, invert the full linear solver Matrix Ax = y for the purpose of the covariance matrix. :return: 1d array of surface brightness pixels of the optimal solution of the linear parameters to match the data

Response:
def image_linear_solve(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_else, inv_bool=False):
        """
        computes the image (lens and source surface brightness with a given lens model).
        The linear parameters are computed with a weighted linear least square optimization (i.e. flux normalization of the brightness profiles)
        :param kwargs_lens: list of keyword arguments corresponding to the superposition of different lens profiles
        :param kwargs_source: list of keyword arguments corresponding to the superposition of different source light profiles
        :param kwargs_lens_light: list of keyword arguments corresponding to different lens light surface brightness profiles
        :param kwargs_else: keyword arguments corresponding to "other" parameters, such as external shear and point source image positions
        :param inv_bool: if True, invert the full linear solver Matrix Ax = y for the purpose of the covariance matrix.
        :return: 1d array of surface brightness pixels of the optimal solution of the linear parameters to match the data
        """
        wls_list, error_map_list, cov_param_list, param_list = [], [], [], []
        for i in range(self._num_bands):
            wls_model, error_map, cov_param, param = self._imageModel_list[i].image_linear_solve(kwargs_lens,
                                                                                kwargs_source,
                                                                                kwargs_lens_light,
                                                                                kwargs_else,
                                                                                inv_bool=inv_bool)
            wls_list.append(wls_model)
            error_map_list.append(error_map)
            cov_param_list.append(cov_param)
            param_list.append(param)
        return wls_list, error_map_list, cov_param_list, param_list


Instruction:
Explain what the following Python 3 code does
def likelihood_data_given_model(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, source_marg=False):
        # generate image
        logL = 0
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                logL += self._imageModel_list[i].likelihood_data_given_model(kwargs_lens, kwargs_source,
                                                                             kwargs_lens_light, kwargs_ps,
                                                                             source_marg=source_marg)
        return logL

Response: computes the likelihood of the data given a model


Instruction:
Can you generate a brief explanation for the following Python 3 code
def image_linear_solve(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, inv_bool=False):
        A = self.linear_response_matrix(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps)
        C_D_response, model_error_list = self.error_response(kwargs_lens, kwargs_ps)
        d = self.data_response
        param, cov_param, wls_model = de_lens.get_param_WLS(A.T, 1 / C_D_response, d, inv_bool=inv_bool)
        kwargs_lens_0 = [kwargs_lens[k] for k in self._idex_lens_list[0]]
        _, _, _, _ = self._imageModel_list[0]._update_linear_kwargs(param, kwargs_lens_0, kwargs_source, kwargs_lens_light, kwargs_ps)
        wls_list = self._array2image_list(wls_model)
        return wls_list, model_error_list, cov_param, param

Response: This method computes the image linear parameters for a given set of parameters.


Instruction:
Can you implement a function in Python 3 that
returns the 1d array of the error estimate corresponding to the data response MimeType

Response:
def error_response(self, kwargs_lens, kwargs_ps):
        """
        returns the 1d array of the error estimate corresponding to the data response

        :return: 1d numpy array of response, 2d array of additonal errors (e.g. point source uncertainties)
        """
        C_D_response, model_error = [], []
        for i in range(self._num_bands):
            if self._compute_bool[i] is True:
                kwargs_lens_i = [kwargs_lens[k] for k in self._idex_lens_list[i]]
                C_D_response_i, model_error_i = self._imageModel_list[i].error_response(kwargs_lens_i, kwargs_ps)
                model_error.append(model_error_i)
                if C_D_response == []:
                    C_D_response = C_D_response_i
                else:
                    C_D_response = np.append(C_D_response, C_D_response_i)
        return C_D_response, model_error


Instruction:
Implement a function in Python 3 to
function to calculate the Gaussian logarithm of the logarithm of the current logarithm.

Response:
def function(self, x, y, amp, sigma_x, sigma_y, center_x=0, center_y=0):
        """
        returns Gaussian
        """
        c = amp/(2*np.pi*sigma_x*sigma_y)
        delta_x = x - center_x
        delta_y = y - center_y
        exponent = -((delta_x/sigma_x)**2+(delta_y/sigma_y)**2)/2.
        return c * np.exp(exponent)


Instruction:
Write a Python 3 function that can
return df dx and df dy of the function

Response:
def derivatives(self, x, y, amp, sigma_x, sigma_y, center_x=0, center_y=0):
        """
        returns df/dx and df/dy of the function
        """
        f_ = self.function(x, y, amp, sigma_x, sigma_y, center_x, center_y)
        return f_ * (center_x-x)/sigma_x**2, f_ * (center_y-y)/sigma_y**2


Instruction:
How would you code a function in Python 3 to
return the Hessian matrix of function f

Response:
def hessian(self, x, y, amp, sigma_x, sigma_y, center_x = 0, center_y = 0):
        """
        returns Hessian matrix of function d^2f/dx^2, d^f/dy^2, d^2/dxdy
        """
        f_ = self.function(x, y, amp, sigma_x, sigma_y, center_x, center_y)
        f_xx = f_ * ( (-1./sigma_x**2) + (center_x-x)**2/sigma_x**4 )
        f_yy = f_ * ( (-1./sigma_y**2) + (center_y-y)**2/sigma_y**4 )
        f_xy = f_ * (center_x-x)/sigma_x**2 * (center_y-y)/sigma_y**2
        return f_xx, f_yy, f_xy


Instruction:
Create a Python 3 function for
calculating M_200 for NFW profile

Response:
def M200(self, Rs, rho0, c):
        """
        M(R_200) calculation for NFW profile

        :param Rs: scale radius
        :type Rs: float
        :param rho0: density normalization (characteristic density)
        :type rho0: float
        :param c: concentration
        :type c: float [4,40]
        :return: M(R_200) density
        """
        return 4*np.pi*rho0*Rs**3*(np.log(1.+c)-c/(1.+c))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def rho0_c(self, c):
        return 200./3*self.rhoc*c**3/(np.log(1.+c)-c/(1.+c))

Response: computes density normalization as a function of concentration parameter


Instruction:
Can you create a Python 3 function that
computes the concentration given a comoving overdensity rho0

Response:
def c_rho0(self, rho0):
        """
        computes the concentration given a comoving overdensity rho0 (inverse of function rho0_c)
        :param rho0: density normalization in h^2/Mpc^3 (comoving)
        :return: concentration parameter c
        """
        if not hasattr(self, '_c_rho0_interp'):
            c_array = np.linspace(0.1, 10, 100)
            rho0_array = self.rho0_c(c_array)
            from scipy import interpolate
            self._c_rho0_interp = interpolate.InterpolatedUnivariateSpline(rho0_array, c_array, w=None, bbox=[None, None], k=3)
        return self._c_rho0_interp(rho0)


Instruction:
Explain what the following Python 3 code does
def c_M_z(self, M, z):
        # fitted parameter values
        A = 5.22
        B = -0.072
        C = -0.42
        M_pivot = 2.*10**12
        return A*(M/M_pivot)**B*(1+z)**C

Response: fitting function of http://moriond. in2p3. fr/J08_proceedings_duffy. pdf for the mass and redshift dependence of the concentration parameter M_sun and redshift dependence of the concentration parameter z


Instruction:
Create a Python 3 function for
returning all needed parameter in comoving units modulo h to draw the profile of the main halo Arc Arc

Response:
def profileMain(self, M, z):
        """
        returns all needed parameter (in comoving units modulo h) to draw the profile of the main halo
        r200 in co-moving Mpc/h
        rho_s in  h^2/Mpc^3 (co-moving)
        Rs in Mpc/h co-moving
        c unit less
        """
        c = self.c_M_z(M, z)
        r200 = self.r200_M(M)
        rho0 = self.rho0_c(c)
        Rs = r200/c
        return r200, rho0, c, Rs


Instruction:
Write a Python 3 function that can
function to reconstruct the model without including the point source contributions as a list

Response:
def image_single_point_source(self, image_model_class, kwargs_lens, kwargs_source, kwargs_lens_light,
                                  kwargs_ps):
        """
        return model without including the point source contributions as a list (for each point source individually)
        :param image_model_class: ImageModel class instance
        :param kwargs_lens: lens model kwargs list
        :param kwargs_source: source model kwargs list
        :param kwargs_lens_light: lens light model kwargs list
        :param kwargs_ps: point source model kwargs list
        :return: list of images with point source isolated
        """
        # reconstructed model with given psf
        model, error_map, cov_param, param = image_model_class.image_linear_solve(kwargs_lens, kwargs_source,
                                                                              kwargs_lens_light, kwargs_ps)
        #model = image_model_class.image(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps)
        data = image_model_class.Data.data
        mask = image_model_class.ImageNumerics.mask
        point_source_list = image_model_class.point_sources_list(kwargs_ps, kwargs_lens)
        n = len(point_source_list)
        model_single_source_list = []
        for i in range(n):
            model_single_source = (data - model + point_source_list[i]) * mask
            model_single_source_list.append(model_single_source)
        return model_single_source_list


Instruction:
How would you explain what the following Python 3 function does
def combine_psf(kernel_list_new, kernel_old, sigma_bkg, factor=1, stacking_option='median', symmetry=1):

        n = int(len(kernel_list_new) * symmetry)
        angle = 360. / symmetry
        kernelsize = len(kernel_old)
        kernel_list = np.zeros((n, kernelsize, kernelsize))
        i = 0
        for kernel_new in kernel_list_new:
            for k in range(symmetry):
                kernel_rotated = image_util.rotateImage(kernel_new, angle * k)
                kernel_norm = kernel_util.kernel_norm(kernel_rotated)
                kernel_list[i, :, :] = kernel_norm
                i += 1

        kernel_old_rotated = np.zeros((symmetry, kernelsize, kernelsize))
        for i in range(symmetry):
            kernel_old_rotated[i, :, :] = kernel_old

        kernel_list_new = np.append(kernel_list, kernel_old_rotated, axis=0)
        if stacking_option == 'median':
            kernel_new = np.median(kernel_list_new, axis=0)
        elif stacking_option == 'mean':
            kernel_new = np.mean(kernel_list_new, axis=0)
        else:
            raise ValueError(" stack_option must be 'median' or 'mean', %s is not supported." % stacking_option)
        kernel_new[kernel_new < 0] = 0
        kernel_new = kernel_util.kernel_norm(kernel_new)
        kernel_return = factor * kernel_new + (1.-factor)* kernel_old

        kernel_bkg = copy.deepcopy(kernel_return)
        kernel_bkg[kernel_bkg < sigma_bkg] = sigma_bkg
        error_map = np.var(kernel_list_new, axis=0) / kernel_bkg**2 / 2.
        return kernel_return, error_map

Response: combine_psf computes the new PSF kernels and error_map for the image


Instruction:
Make a summary of the following Python 3 code
def logLikelihood(self, D_d, D_delta_t):
        if self._kde_type == 'scipy_gaussian':
            density = self._PDF_kernel([D_d, D_delta_t])
            logL = np.log(density)
        else:
            x = np.array([[D_d], [D_delta_t]])
            logL = self._kde.score_samples(x.T)
        return logL

Response: This method calculates the log likelihood of the data given a model with predicted angular diameter distances and time - delays.


Instruction:
Implement a Python 3 function for
computing the density of the n - tuple

Response:
def density(self, r, rho0, Rs):
        """
        computes the density
        :param x:
        :param y:
        :param rho0:
        :param a:
        :param s:
        :return:
        """
        rho = rho0 / (r/Rs * (1 + (r/Rs))**3)
        return rho


Instruction:
Given the following Python 3 function, write the documentation
def density_2d(self, x, y, rho0, Rs, center_x=0, center_y=0):
        x_ = x - center_x
        y_ = y - center_y
        r = np.sqrt(x_**2 + y_**2)
        X = r/Rs
        sigma0 = self.rho2sigma(rho0, Rs)
        if isinstance(X, int) or isinstance(X, float):
            if X == 1:
                X = 1.000001
        else:
            X[X == 1] = 1.000001
        sigma = sigma0 / (X**2-1)**2 * (-3 + (2+X**2)*self._F(X))
        return sigma

Response: projected density of a 2D logarithmic resource.


Instruction:
Can you write a function in Python 3 where it
calculates the mass of a 3d sphere or radius r

Response:
def mass_3d(self, r, rho0, Rs):
        """
        mass enclosed a 3d sphere or radius r
        :param r:
        :param a:
        :param s:
        :return:
        """
        mass_3d = 2*np.pi*Rs**3*rho0 * r**2/(r + Rs)**2
        return mass_3d


Instruction:
Explain what the following Python 3 code does
def mass_3d_lens(self, r, sigma0, Rs):
        rho0 = self.sigma2rho(sigma0, Rs)
        return self.mass_3d(r, rho0, Rs)

Response: mass enclosed a 3d sphere or radius r for lens parameterisation


Instruction:
Given the following Python 3 function, write the documentation
def mass_2d(self, r, rho0, Rs):

        sigma0 = self.rho2sigma(rho0, Rs)
        return self.mass_2d_lens(r, sigma0, Rs)

Response: return the mass enclosed projected 2d sphere of radius r


Instruction:
How would you code a function in Python 3 to
calculate 2d mass of a 2d sphere of radius r

Response:
def mass_2d_lens(self, r, sigma0, Rs):
        """
        mass enclosed projected 2d sphere of radius r
        :param r:
        :param rho0:
        :param a:
        :param s:
        :return:
        """
        X = r/Rs
        alpha_r = 2*sigma0 * Rs * X * (1-self._F(X)) / (X**2-1)
        mass_2d = alpha_r * r * np.pi
        return mass_2d


Instruction:
How would you implement a function in Python 3 that
calculates total mass within the profile

Response:
def mass_tot(self, rho0, Rs):
        """
        total mass within the profile
        :param rho0:
        :param a:
        :param s:
        :return:
        """
        m_tot = 2*np.pi*rho0*Rs**3
        return m_tot


Instruction:
Can you generate the documentation for the following Python 3 function
def ray_shooting(self, x, y, kwargs, k=None):
        return self.lens_model.ray_shooting(x, y, kwargs, k=k)

Response: ray shooting for the image


Instruction:
How would you code a function in Python 3 to
return the fermat potential of the image at the given location

Response:
def fermat_potential(self, x_image, y_image, x_source, y_source, kwargs_lens):
        """
        fermat potential (negative sign means earlier arrival time)

        :param x_image: image position
        :param y_image: image position
        :param x_source: source position
        :param y_source: source position
        :param kwargs_lens: list of keyword arguments of lens model parameters matching the lens model classes
        :return: fermat potential in arcsec**2 without geometry term (second part of Eqn 1 in Suyu et al. 2013) as a list
        """
        if hasattr(self.lens_model, 'fermat_potential'):
            return self.lens_model.fermat_potential(x_image, y_image, x_source, y_source, kwargs_lens)
        else:
            raise ValueError("Fermat potential is not defined in multi-plane lensing. Please use single plane lens models.")


Instruction:
How would you explain what the following Python 3 function does
def potential(self, x, y, kwargs, k=None):
        return self.lens_model.potential(x, y, kwargs, k=k)

Response:
lensing potential

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: lensing potential in units of arcsec^2


Instruction:
Can you implement a function in Python 3 that
returns the deflection angles of the current set of lens models

Response:
def alpha(self, x, y, kwargs, k=None):
        """
        deflection angles

        :param x: x-position (preferentially arcsec)
        :type x: numpy array
        :param y: y-position (preferentially arcsec)
        :type y: numpy array
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param k: only evaluate the k-th lens model
        :return: deflection angles in units of arcsec
        """
        return self.lens_model.alpha(x, y, kwargs, k=k)


Instruction:
Can you generate the documentation for the following Python 3 function
def hessian(self, x, y, kwargs, k=None):
        return self.lens_model.hessian(x, y, kwargs, k=k)

Response: compute the hessian of the current set of components


Instruction:
How would you explain what the following Python 3 function does
def flexion(self, x, y, kwargs, diff=0.000001):
        f_xx, f_xy, f_yx, f_yy = self.hessian(x, y, kwargs)

        f_xx_dx, f_xy_dx, f_yx_dx, f_yy_dx = self.hessian(x + diff, y, kwargs)
        f_xx_dy, f_xy_dy, f_yx_dy, f_yy_dy = self.hessian(x, y + diff, kwargs)

        f_xxx = (f_xx_dx - f_xx) / diff
        f_xxy = (f_xx_dy - f_xx) / diff
        f_xyy = (f_xy_dy - f_xy) / diff
        f_yyy = (f_yy_dy - f_yy) / diff
        return f_xxx, f_xxy, f_xyy, f_yyy

Response: flexion is the inverse of the hessian function


Instruction:
Can you tell what is the following Python 3 function doing
def X2_chain_omega_mh2(self, args):
        H0 = args[0]
        h = H0/100.
        omega_m = self.omega_mh2_fixed / h**2
        Ode0 = self._omega_lambda_fixed
        logL, bool = self.prior_omega_mh2(h, omega_m)
        if bool is True:
            logL += self.LCDM_lensLikelihood(H0, omega_m, Ode0)
        return logL, None

Response: X2_chain_omega_mh2 routine to compute the log likelihood given a omega_m h ** 2 prior fixed


Instruction:
Can you tell what is the following Python 3 function doing
def prior_H0(self, H0, H0_min=0, H0_max=200):
        if H0 < H0_min or H0 > H0_max:
            penalty = -10**15
            return penalty, False
        else:
            return 0, True

Response: checks whether the parameter vector has left its bound adds a big number to the prior H0


Instruction:
How would you code a function in Python 3 to
check whether the parameter omega_m is within the given bounds and returns the penalty and a boolean indicating if the parameter omega_m is prior to the given omega_m_min and omega_m_max.

Response:
def prior_omega_m(self, omega_m, omega_m_min=0, omega_m_max=1):
        """
        checks whether the parameter omega_m is within the given bounds
        :param omega_m:
        :param omega_m_min:
        :param omega_m_max:
        :return:
        """
        if omega_m < omega_m_min or omega_m > omega_m_max:
            penalty = -10**15
            return penalty, False
        else:
            return 0, True


Instruction:
Explain what the following Python 3 code does
def mcmc_emcee(self, n_walkers, n_run, n_burn, mean_start, sigma_start):
        sampler = emcee.EnsembleSampler(n_walkers, self.cosmoParam.numParam, self.chain.likelihood)
        p0 = emcee.utils.sample_ball(mean_start, sigma_start, n_walkers)
        new_pos, _, _, _ = sampler.run_mcmc(p0, n_burn)
        sampler.reset()
        store = InMemoryStorageUtil()
        for pos, prob, _, _ in sampler.sample(new_pos, iterations=n_run):
            store.persistSamplingValues(pos, prob, None)
        return store.samples

Response: Runs the mcmc analysis of the parameter space.


Instruction:
How would you implement a function in Python 3 that
configures the data keyword arguments with a coordinate grid centered at zero. :param numPix: number of pixel (numPix x numPix) :param deltaPix: pixel size (in angular units) :param exposure_time: exposure time :param sigma_bkg: background noise (Gaussian sigma) :param inverse: if True, coordinate system is ra to the left, if False, to the right :return: keyword arguments that can be used to construct a Data() class instance of lenstronomy

Response:
def data_configure_simple(numPix, deltaPix, exposure_time=1, sigma_bkg=1, inverse=False):
    """
    configures the data keyword arguments with a coordinate grid centered at zero.

    :param numPix: number of pixel (numPix x numPix)
    :param deltaPix: pixel size (in angular units)
    :param exposure_time: exposure time
    :param sigma_bkg: background noise (Gaussian sigma)
    :param inverse: if True, coordinate system is ra to the left, if False, to the right
    :return: keyword arguments that can be used to construct a Data() class instance of lenstronomy
    """
    mean = 0.  # background mean flux (default zero)
    # 1d list of coordinates (x,y) of a numPix x numPix square grid, centered to zero
    x_grid, y_grid, ra_at_xy_0, dec_at_xy_0, x_at_radec_0, y_at_radec_0, Mpix2coord, Mcoord2pix = util.make_grid_with_coordtransform(numPix=numPix, deltapix=deltaPix, subgrid_res=1, inverse=inverse)
    # mask (1= model this pixel, 0= leave blanck)
    exposure_map = np.ones((numPix, numPix)) * exposure_time  # individual exposure time/weight per pixel

    kwargs_data = {
        'background_rms': sigma_bkg,
        'exposure_map': exposure_map
        , 'ra_at_xy_0': ra_at_xy_0, 'dec_at_xy_0': dec_at_xy_0, 'transform_pix2angle': Mpix2coord
        , 'image_data': np.zeros((numPix, numPix))
        }
    return kwargs_data


Instruction:
Here you have a function in Python 3, explain what it does
def psf_configure_simple(psf_type="GAUSSIAN", fwhm=1, kernelsize=11, deltaPix=1, truncate=6, kernel=None):

    if psf_type == 'GAUSSIAN':
        sigma = util.fwhm2sigma(fwhm)
        sigma_axis = sigma
        gaussian = Gaussian()
        x_grid, y_grid = util.make_grid(kernelsize, deltaPix)
        kernel_large = gaussian.function(x_grid, y_grid, amp=1., sigma_x=sigma_axis, sigma_y=sigma_axis, center_x=0, center_y=0)
        kernel_large /= np.sum(kernel_large)
        kernel_large = util.array2image(kernel_large)
        kernel_pixel = kernel_util.pixel_kernel(kernel_large)
        kwargs_psf = {'psf_type': psf_type, 'fwhm': fwhm, 'truncation': truncate*fwhm, 'kernel_point_source': kernel_large, 'kernel_pixel': kernel_pixel, 'pixel_size': deltaPix}
    elif psf_type == 'PIXEL':
        kernel_large = copy.deepcopy(kernel)
        kernel_large = kernel_util.cut_psf(kernel_large, psf_size=kernelsize)
        kwargs_psf = {'psf_type': "PIXEL", 'kernel_point_source': kernel_large}
    elif psf_type == 'NONE':
        kwargs_psf = {'psf_type': 'NONE'}
    else:
        raise ValueError("psf type %s not supported!" % psf_type)
    return kwargs_psf

Response: This routine initializes a PSF class in lenstronomy with the given parameters.


Instruction:
Can you generate the documentation for the following Python 3 function
def _theta_E_convert(self, theta_E, w_c, w_t):
        if not w_t > w_c:
            w_t, w_c = w_c, w_t
        s_scale_1 = w_c
        s_scale_2 = w_t
        f_x_1, f_y_1 = self.nie.derivatives(1, 0, theta_E=1, e1=0, e2=0, s_scale=s_scale_1)
        f_x_2, f_y_2 = self.nie.derivatives(1, 0, theta_E=1, e1=0, e2=0, s_scale=s_scale_2)
        f_x = f_x_1 - f_x_2
        theta_E_convert = theta_E / f_x
        return theta_E_convert, w_c, w_t

Response: convert the parameter theta_E into the parameter w_c w_t


Instruction:
Make a summary of the following Python 3 code
def derivatives(self, x, y, center_x = 0, center_y = 0, **kwargs):

        """
        returns df/dx and df/dy (un-normalized!!!) interpolated from the numerical deflection table
        """

        assert 'norm' in kwargs.keys(), "key word arguments must contain 'norm', " \
                                        "the normalization of deflection angle in units of arcsec."

        x_ = x - center_x
        y_ = y - center_y
        R = np.sqrt(x_**2 + y_**2)

        alpha = self._interp(x_, y_, **kwargs)

        cos_theta = x_ * R ** -1
        sin_theta = y_ * R ** -1

        f_x, f_y = alpha * cos_theta, alpha * sin_theta

        return f_x, f_y

Response: returns df dx dy interpolated from the numerical deflection table


Instruction:
Can you write a function in Python 3 where it
returns the Hessian matrix of function d^2f dx y d^2 f dy and f xy

Response:
def hessian(self, x, y, center_x = 0, center_y = 0, **kwargs):
        """
        returns Hessian matrix of function d^2f/dx^2, d^f/dy^2, d^2/dxdy
        (un-normalized!!!) interpolated from the numerical deflection table
        """

        diff = 1e-6
        alpha_ra, alpha_dec = self.derivatives(x, y, center_x = center_x, center_y = center_y,
                                               **kwargs)

        alpha_ra_dx, alpha_dec_dx = self.derivatives(x + diff, y, center_x = center_x, center_y = center_y,
                                               **kwargs)
        alpha_ra_dy, alpha_dec_dy = self.derivatives(x, y + diff, center_x = center_x, center_y = center_y,
                                               **kwargs)

        dalpha_rara = (alpha_ra_dx - alpha_ra) / diff
        dalpha_radec = (alpha_ra_dy - alpha_ra) / diff
        dalpha_decdec = (alpha_dec_dy - alpha_dec) / diff

        f_xx = dalpha_rara
        f_yy = dalpha_decdec
        f_xy = dalpha_radec

        return f_xx, f_yy, f_xy


Instruction:
Can you generate a brief explanation for the following Python 3 code
def derivatives(self, x, y, n_sersic, R_sersic, k_eff, e1, e2, center_x=0, center_y=0):
        phi_G, q = param_util.ellipticity2phi_q(e1, e2)
        e = abs(1. - q)
        cos_phi = np.cos(phi_G)
        sin_phi = np.sin(phi_G)
        x_, y_ = self._coord_transf(x, y, q, phi_G, center_x, center_y)
        f_x_prim, f_y_prim = self.sersic.derivatives(x_, y_, n_sersic, R_sersic, k_eff)
        f_x_prim *= np.sqrt(1 - e)
        f_y_prim *= np.sqrt(1 + e)
        f_x = cos_phi*f_x_prim-sin_phi*f_y_prim
        f_y = sin_phi*f_x_prim+cos_phi*f_y_prim
        return f_x, f_y

Response: returns df x y of the function that is derivatives of the sersic function


Instruction:
How would you explain what the following Python 3 function does
def add_layer2image(grid2d, x_pos, y_pos, kernel, order=1):

    x_int = int(round(x_pos))
    y_int = int(round(y_pos))
    shift_x = x_int - x_pos
    shift_y = y_int - y_pos
    kernel_shifted = interp.shift(kernel, [-shift_y, -shift_x], order=order)
    return add_layer2image_int(grid2d, x_int, y_int, kernel_shifted)

Response: Adds a kernel on the grid2d image at position x_pos y_pos and returns the image with the added layer cut to original size


Instruction:
Given the following Python 3 function, write the documentation
def add_layer2image_int(grid2d, x_pos, y_pos, kernel):
    nx, ny = np.shape(kernel)
    if nx % 2 == 0:
        raise ValueError("kernel needs odd numbers of pixels")

    num_x, num_y = np.shape(grid2d)
    x_int = int(round(x_pos))
    y_int = int(round(y_pos))

    k_x, k_y = np.shape(kernel)
    k_l2_x = int((k_x - 1) / 2)
    k_l2_y = int((k_y - 1) / 2)

    min_x = np.maximum(0, x_int-k_l2_x)
    min_y = np.maximum(0, y_int-k_l2_y)
    max_x = np.minimum(num_x, x_int+k_l2_x + 1)
    max_y = np.minimum(num_y, y_int+k_l2_y + 1)

    min_xk = np.maximum(0, -x_int + k_l2_x)
    min_yk = np.maximum(0, -y_int + k_l2_y)
    max_xk = np.minimum(k_x, -x_int + k_l2_x + num_x)
    max_yk = np.minimum(k_y, -y_int + k_l2_y + num_y)
    if min_x >= max_x or min_y >= max_y or min_xk >= max_xk or min_yk >= max_yk or (max_x-min_x != max_xk-min_xk) or (max_y-min_y != max_yk-min_yk):
        return grid2d
    kernel_re_sized = kernel[min_yk:max_yk, min_xk:max_xk]
    new = grid2d.copy()
    new[min_y:max_y, min_x:max_x] += kernel_re_sized
    return new

Response: Adds a kernel on the grid2d image at position x_pos y_pos at integer positions of pixel


Instruction:
Write a Python 3 script to
add background noise to the image

Response:
def add_background(image, sigma_bkd):
    """
    adds background noise to image
    :param image: pixel values of image
    :param sigma_bkd: background noise (sigma)
    :return: a realisation of Gaussian noise of the same size as image
    """
    if sigma_bkd < 0:
        raise ValueError("Sigma background is smaller than zero! Please use positive values.")
    nx, ny = np.shape(image)
    background = np.random.randn(nx, ny) * sigma_bkd
    return background


Instruction:
Can you tell what is the following Python 3 function doing
def add_poisson(image, exp_time):
    """
    adds a poison (or Gaussian) distributed noise with mean given by surface brightness
    """
    if isinstance(exp_time, int) or isinstance(exp_time, float):
        if exp_time <= 0:
            exp_time = 1
    else:
        mean_exp_time = np.mean(exp_time)
        exp_time[exp_time < mean_exp_time/10] = mean_exp_time/10
    sigma = np.sqrt(np.abs(image)/exp_time) # Gaussian approximation for Poisson distribution, normalized to exposure time
    nx, ny = np.shape(image)
    poisson = np.random.randn(nx, ny) * sigma
    return poisson

Response: Adds a poison or Gaussian realization of input image to the next image in the next image.


Instruction:
Explain what the following Python 3 code does
def re_size_array(x_in, y_in, input_values, x_out, y_out):
    interp_2d = scipy.interpolate.interp2d(x_in, y_in, input_values, kind='linear')
    #interp_2d = scipy.interpolate.RectBivariateSpline(x_in, y_in, input_values, kx=1, ky=1)
    out_values = interp_2d.__call__(x_out, y_out)
    return out_values

Response: Resizes 2d array to new coordinates.


Instruction:
Can you write a function in Python 3 where it
gets the symmetrical image of the image

Response:
def symmetry_average(image, symmetry):
    """
    symmetry averaged image
    :param image:
    :param symmetry:
    :return:
    """
    img_sym = np.zeros_like(image)
    angle = 360./symmetry
    for i in range(symmetry):
        img_sym += rotateImage(image, angle*i)
    img_sym /= symmetry
    return img_sym


Instruction:
Make a summary of the following Python 3 code
def findOverlap(x_mins, y_mins, min_distance):
    n = len(x_mins)
    idex = []
    for i in range(n):
        if i == 0:
            pass
        else:
            for j in range(0, i):
                if (abs(x_mins[i] - x_mins[j]) < min_distance and abs(y_mins[i] - y_mins[j]) < min_distance):
                    idex.append(i)
                    break
    x_mins = np.delete(x_mins, idex, axis=0)
    y_mins = np.delete(y_mins, idex, axis=0)
    return x_mins, y_mins

Response: Find overlapping solutions deletes multiples and deletes non - solutions and deletes multiples and deletes non - solutions and returns x_mins y_mins


Instruction:
Write a Python 3 function that can
check whether image positions are within the image in units of arcsec

Response:
def coordInImage(x_coord, y_coord, numPix, deltapix):
    """
    checks whether image positions are within the pixel image in units of arcsec
    if not: remove it

    :param imcoord: image coordinate (in units of angels)  [[x,y,delta,magnification][...]]
    :type imcoord: (n,4) numpy array
    :returns: image positions within the pixel image
    """
    idex=[]
    min = -deltapix*numPix/2
    max = deltapix*numPix/2
    for i in range(len(x_coord)): #sum over image positions
        if (x_coord[i] < min or x_coord[i] > max or y_coord[i] < min or y_coord[i] > max):
            idex.append(i)
    x_coord = np.delete(x_coord, idex, axis=0)
    y_coord = np.delete(y_coord, idex, axis=0)
    return x_coord, y_coord


Instruction:
Implement a Python 3 function for
adopting coordinate system and transformation between angular and pixel coordinates of a re-binned image :param bin_size: :param ra_0: :param dec_0: :param x_0: :param y_0: :param Matrix: :param Matrix_inv: :return:

Response:
def rebin_coord_transform(factor, x_at_radec_0, y_at_radec_0, Mpix2coord, Mcoord2pix):
    """
    adopt coordinate system and transformation between angular and pixel coordinates of a re-binned image
    :param bin_size:
    :param ra_0:
    :param dec_0:
    :param x_0:
    :param y_0:
    :param Matrix:
    :param Matrix_inv:
    :return:
    """
    factor = int(factor)
    Mcoord2pix_resized = Mcoord2pix / factor
    Mpix2coord_resized = Mpix2coord * factor
    x_at_radec_0_resized = (x_at_radec_0 + 0.5) / factor - 0.5
    y_at_radec_0_resized = (y_at_radec_0 + 0.5) / factor - 0.5
    ra_at_xy_0_resized, dec_at_xy_0_resized = util.map_coord2pix(-x_at_radec_0_resized, -y_at_radec_0_resized, 0, 0, Mpix2coord_resized)
    return ra_at_xy_0_resized, dec_at_xy_0_resized, x_at_radec_0_resized, y_at_radec_0_resized, Mpix2coord_resized, Mcoord2pix_resized


Instruction:
Explain what the following Python 3 code does
def stack_images(image_list, wht_list, sigma_list):
    image_stacked = np.zeros_like(image_list[0])
    wht_stacked = np.zeros_like(image_stacked)
    sigma_stacked = 0.
    for i in range(len(image_list)):
        image_stacked += image_list[i]*wht_list[i]
        sigma_stacked += sigma_list[i]**2 * np.median(wht_list[i])
        wht_stacked += wht_list[i]
    image_stacked /= wht_stacked
    sigma_stacked /= np.median(wht_stacked)
    wht_stacked /= len(wht_list)
    return image_stacked, wht_stacked, np.sqrt(sigma_stacked)

Response: stacks images and saves new image as a fits file


Instruction:
Can you create a Python 3 function that
cuts out the edges of a 2d image and returns re-sized image to numPix center is well defined for odd pixel sizes. :param image: 2d numpy array :param numPix: square size of cut out image :return: cutout image with size numPix

Response:
def cut_edges(image, numPix):
    """
    cuts out the edges of a 2d image and returns re-sized image to numPix
    center is well defined for odd pixel sizes.
    :param image: 2d numpy array
    :param numPix: square size of cut out image
    :return: cutout image with size numPix
    """
    nx, ny = image.shape
    if nx < numPix or ny < numPix:
        print('WARNING: image can not be resized, in routine cut_edges.')
        return image
    if nx % 2 == 0 or ny % 2 == 0 or numPix % 2 == 0:
        #pass
        print("WARNING: image or cutout side are even number. This routine only works for odd numbers %s %s %s"
                         % (nx, ny, numPix))
    cx = int((nx-1)/2)
    cy = int((ny-1)/2)
    d = int((numPix-1)/2)
    if nx % 2 == 0:
        cx += 1
    if ny % 2 == 0:
        cy += 1
    resized = image[cx-d:cx+d+1, cy-d:cy+d+1]
    return copy.deepcopy(resized)


Instruction:
Can you generate the documentation for the following Python 3 function
def _make_interpolation(self):
        H0_range = np.linspace(10, 100, 90)
        omega_m_range = np.linspace(0.05, 1, 95)
        grid2d = np.dstack(np.meshgrid(H0_range, omega_m_range)).reshape(-1, 2)
        H0_grid = grid2d[:, 0]
        omega_m_grid = grid2d[:, 1]
        Dd_grid = np.zeros_like(H0_grid)
        Ds_Dds_grid = np.zeros_like(H0_grid)
        for i in range(len(H0_grid)):
            Dd, Ds_Dds = self.cosmo2Dd_Ds_Dds(H0_grid[i], omega_m_grid[i])
            Dd_grid[i] = Dd
            Ds_Dds_grid[i] = Ds_Dds
        self._f_H0 = interpolate.interp2d(Dd_grid, Ds_Dds_grid, H0_grid, kind='linear', copy=False, bounds_error=False, fill_value=-1)
        print("H0 interpolation done")
        self._f_omega_m = interpolate.interp2d(Dd_grid, Ds_Dds_grid, omega_m_grid, kind='linear', copy=False, bounds_error=False, fill_value=-1)
        print("omega_m interpolation done")

Response: Creates an interpolation grid in H_0 omega_m and computes quantities in Dd and Ds_Dds


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_cosmo(self, Dd, Ds_Dds):
        if not hasattr(self, '_f_H0') or not hasattr(self, '_f_omega_m'):
            self._make_interpolation()
        H0 = self._f_H0(Dd, Ds_Dds)
        print(H0, 'H0')
        omega_m = self._f_omega_m(Dd, Ds_Dds)
        Dd_new, Ds_Dds_new = self.cosmo2Dd_Ds_Dds(H0[0], omega_m[0])
        if abs(Dd - Dd_new)/Dd > 0.01 or abs(Ds_Dds - Ds_Dds_new)/Ds_Dds > 0.01:
            return [-1], [-1]
        else:
            return H0[0], omega_m[0]

Response: get_cosmo - Get the values of H0 and omega_m computed with an interpolation


Instruction:
Explain what the following Python 3 code does
def mass_enclosed_3d(self, r, kwargs_profile):
        kwargs = copy.deepcopy(kwargs_profile)
        try:
            del kwargs['center_x']
            del kwargs['center_y']
        except:
            pass
        # integral of self._profile.density(x)* 4*np.pi * x^2 *dx, 0,r
        out = integrate.quad(lambda x: self._profile.density(x, **kwargs)*4*np.pi*x**2, 0, r)
        return out[0]

Response: computes the 3d mass enclosed within a sphere of radius r


Instruction:
Explain what the following Python 3 code does
def density_2d(self, r, kwargs_profile):
        kwargs = copy.deepcopy(kwargs_profile)
        try:
            del kwargs['center_x']
            del kwargs['center_y']
        except:
            pass
        # integral of self._profile.density(np.sqrt(x^2+r^2))* dx, 0, infty
        out = integrate.quad(lambda x: 2*self._profile.density(np.sqrt(x**2+r**2), **kwargs), 0, 100)
        return out[0]

Response: computes the projected density along the line - of - sight


Instruction:
Can you generate the documentation for the following Python 3 function
def mass_enclosed_2d(self, r, kwargs_profile):
        kwargs = copy.deepcopy(kwargs_profile)
        try:
            del kwargs['center_x']
            del kwargs['center_y']
        except:
            pass
        # integral of self.density_2d(x)* 2*np.pi * x *dx, 0, r
        out = integrate.quad(lambda x: self.density_2d(x, kwargs)*2*np.pi*x, 0, r)
        return out[0]

Response: computes the mass enclosed by projected line - of - sight


Instruction:
Here you have a function in Python 3, explain what it does
def shift_coordinate_grid(self, x_shift, y_shift, pixel_unit=False):
        self._coords.shift_coordinate_grid(x_shift, y_shift, pixel_unit=pixel_unit)
        self._x_grid, self._y_grid = self._coords.coordinate_grid(self.nx)

Response: shifts the coordinate grid of the data class with the given shift in x and y


Instruction:
How would you explain what the following Python 3 function does
def C_D(self):
        if not hasattr(self, '_C_D'):
            if self._noise_map is not None:
                self._C_D = self._noise_map**2
            else:
                self._C_D = self.covariance_matrix(self.data, self.background_rms, self.exposure_map)
        return self._C_D

Response: Returns the covariance matrix of all pixel values in 2d numpy array.


Instruction:
Can you tell what is the following Python 3 function doing
def covariance_matrix(self, data, background_rms=1, exposure_map=1, noise_map=None, verbose=False):
        if noise_map is not None:
            return noise_map**2
        if isinstance(exposure_map, int) or isinstance(exposure_map, float):
            if exposure_map <= 0:
                exposure_map = 1
        else:
            mean_exp_time = np.mean(exposure_map)
            exposure_map[exposure_map < mean_exp_time / 10] = mean_exp_time / 10
        if verbose:
            if background_rms * np.max(exposure_map) < 1:
                print("WARNING! sigma_b*f %s < 1 count may introduce unstable error estimates" % (background_rms * np.max(exposure_map)))
        d_pos = np.zeros_like(data)
        #threshold = 1.5*sigma_b
        d_pos[data >= 0] = data[data >= 0]
        #d_pos[d < threshold] = 0
        sigma = d_pos / exposure_map + background_rms ** 2
        return sigma

Response: returns the diagonal matrix that describes the error of the background and Poisson components of the noise estimate


Instruction:
Here you have a function in Python 3, explain what it does
def image_position_stochastic(self, source_x, source_y, kwargs_lens, search_window=10,
                                  precision_limit=10**(-10), arrival_time_sort=True, x_center=0,
                                  y_center=0, num_random=1000, verbose=False):
        """
        Solves the lens equation stochastically with the scipy minimization routine on the quadratic distance between
        the backwards ray-shooted proposed image position and the source position.
        Credits to Giulia Pagano

        :param source_x: source position
        :param source_y: source position
        :param kwargs_lens: lens model list of keyword arguments
        :param search_window: angular size of search window
        :param precision_limit: limit required on the precision in the source plane
        :param arrival_time_sort: bool, if True sorts according to arrival time
        :param x_center: center of search window
        :param y_center: center of search window
        :param num_random: number of random starting points of the non-linear solver in the search window
        :param verbose: bool, if True, prints performance information
        :return: x_image, y_image
        """
        x_solve, y_solve = [], []
        for i in range(num_random):
            x_init = np.random.uniform(-search_window / 2., search_window / 2) + x_center
            y_init = np.random.uniform(-search_window / 2., search_window / 2) + y_center
            xinitial = np.array([x_init, y_init])
            result = minimize(self._root, xinitial, args=(kwargs_lens, source_x, source_y), tol=precision_limit ** 2, method='Nelder-Mead')
            if self._root(result.x, kwargs_lens, source_x, source_y) < precision_limit**2:
                x_solve.append(result.x[0])
                y_solve.append(result.x[1])

        x_mins, y_mins = image_util.findOverlap(x_solve, y_solve, precision_limit)
        if arrival_time_sort is True:
            x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins, kwargs_lens)
        return x_mins, y_mins

Response: Solves the lens equation stochastically with the scipy minimization routine on the quadratic distance between the source position and the proposed image position.


Instruction:
Here you have a function in Python 3, explain what it does
def image_position_from_source(self, sourcePos_x, sourcePos_y, kwargs_lens, min_distance=0.1, search_window=10,
                                   precision_limit=10**(-10), num_iter_max=100, arrival_time_sort=True,
                                   initial_guess_cut=True, verbose=False, x_center=0, y_center=0, num_random=0):
        """
        finds image position source position and lense model

        :param sourcePos_x: source position in units of angle
        :param sourcePos_y: source position in units of angle
        :param kwargs_lens: lens model parameters as keyword arguments
        :param min_distance: minimum separation to consider for two images in units of angle
        :param search_window: window size to be considered by the solver. Will not find image position outside this window
        :param precision_limit: required precision in the lens equation solver (in units of angle in the source plane).
        :param num_iter_max: maximum iteration of lens-source mapping conducted by solver to match the required precision
        :param arrival_time_sort: bool, if True, sorts image position in arrival time (first arrival photon first listed)
        :param initial_guess_cut: bool, if True, cuts initial local minima selected by the grid search based on distance criteria from the source position
        :param verbose: bool, if True, prints some useful information for the user
        :param x_center: float, center of the window to search for point sources
        :param y_center: float, center of the window to search for point sources
        :returns: (exact) angular position of (multiple) images ra_pos, dec_pos in units of angle
        :raises: AttributeError, KeyError
        """

        # compute number of pixels to cover the search window with the required min_distance
        numPix = int(round(search_window / min_distance) + 0.5)
        x_grid, y_grid = util.make_grid(numPix, min_distance)
        x_grid += x_center
        y_grid += y_center
        # ray-shoot to find the relative distance to the required source position for each grid point
        x_mapped, y_mapped = self.lensModel.ray_shooting(x_grid, y_grid, kwargs_lens)
        absmapped = util.displaceAbs(x_mapped, y_mapped, sourcePos_x, sourcePos_y)
        # select minima in the grid points and select grid points that do not deviate more than the
        # width of the grid point to a solution of the lens equation
        x_mins, y_mins, delta_map = util.neighborSelect(absmapped, x_grid, y_grid)
        if verbose is True:
            print("There are %s regions identified that could contain a solution of the lens equation" % len(x_mins))
        #mag = np.abs(mag)
        #print(x_mins, y_mins, 'before requirement of min_distance')
        if initial_guess_cut is True:
            mag = np.abs(self.lensModel.magnification(x_mins, y_mins, kwargs_lens))
            mag[mag < 1] = 1
            x_mins = x_mins[delta_map <= min_distance*mag*5]
            y_mins = y_mins[delta_map <= min_distance*mag*5]
            if verbose is True:
                print("The number of regions that meet the plausibility criteria are %s" % len(x_mins))
        x_mins = np.append(x_mins, np.random.uniform(low=-search_window/2+x_center, high=search_window/2+x_center,
                                                     size=num_random))
        y_mins = np.append(y_mins, np.random.uniform(low=-search_window / 2 + y_center, high=search_window / 2 + y_center,
                                             size=num_random))
        # iterative solving of the lens equation for the selected grid points
        x_mins, y_mins, solver_precision = self._findIterative(x_mins, y_mins, sourcePos_x, sourcePos_y, kwargs_lens,
                                                               precision_limit, num_iter_max, verbose=verbose,
                                                               min_distance=min_distance)
        # only select iterative results that match the precision limit
        x_mins = x_mins[solver_precision <= precision_limit]
        y_mins = y_mins[solver_precision <= precision_limit]
        # find redundant solutions within the min_distance criterion
        x_mins, y_mins = image_util.findOverlap(x_mins, y_mins, min_distance)
        if arrival_time_sort is True:
            x_mins, y_mins = self.sort_arrival_times(x_mins, y_mins, kwargs_lens)
        #x_mins, y_mins = lenstronomy_util.coordInImage(x_mins, y_mins, numPix, deltapix)
        return x_mins, y_mins

Response: finds image position from source position and lense model


Instruction:
Write a Python 3 function for
sorting arrival times of images in increasing order of light travel time

Response:
def sort_arrival_times(self, x_mins, y_mins, kwargs_lens):
        """
        sort arrival times (fermat potential) of image positions in increasing order of light travel time
        :param x_mins: ra position of images
        :param y_mins: dec position of images
        :param kwargs_lens: keyword arguments of lens model
        :return: sorted lists of x_mins and y_mins
        """

        if hasattr(self.lensModel, '_no_potential'):
            raise Exception('Instance of lensModel passed to this class does not compute the lensing potential, '
                            'and therefore cannot compute time delays.')

        if len(x_mins) <= 1:
            return x_mins, y_mins
        x_source, y_source = self.lensModel.ray_shooting(x_mins, y_mins, kwargs_lens)
        x_source = np.mean(x_source)
        y_source = np.mean(y_source)
        if self.lensModel.multi_plane is True:
            arrival_time = self.lensModel.arrival_time(x_mins, y_mins, kwargs_lens)
        else:
            fermat_pot = self.lensModel.fermat_potential(x_mins, y_mins, x_source, y_source, kwargs_lens)
            arrival_time = fermat_pot
        idx = np.argsort(arrival_time)
        x_mins = np.array(x_mins)[idx]
        y_mins = np.array(y_mins)[idx]
        return x_mins, y_mins


Instruction:
Can you generate the documentation for the following Python 3 function
def check_positive_flux(cls, kwargs_ps):
        pos_bool = True
        for kwargs in kwargs_ps:
            point_amp = kwargs['point_amp']
            for amp in point_amp:
                if amp < 0:
                    pos_bool = False
                    break
        return pos_bool

Response:
check whether inferred linear parameters are positive
COOKIEID


Instruction:
Create a Python 3 function to
return the log likelihood of the best fit model of the current state of this class

Response:
def best_fit_likelihood(self):
        """
        returns the log likelihood of the best fit model of the current state of this class

        :return: log likelihood, float
        """
        kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, kwargs_cosmo = self.best_fit(bijective=False)
        param_class = self._param_class
        likelihoodModule = self.likelihoodModule
        logL, _ = likelihoodModule.logL(param_class.kwargs2args(kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps,
                                                             kwargs_cosmo))
        return logL


Instruction:
Here you have a function in Python 3, explain what it does
def mcmc(self, n_burn, n_run, walkerRatio, sigma_scale=1, threadCount=1, init_samples=None, re_use_samples=True):

        param_class = self._param_class
        # run PSO
        mcmc_class = Sampler(likelihoodModule=self.likelihoodModule)
        mean_start = param_class.kwargs2args(self._lens_temp, self._source_temp, self._lens_light_temp, self._ps_temp,
                                           self._cosmo_temp)
        lens_sigma, source_sigma, lens_light_sigma, ps_sigma, cosmo_sigma = self._updateManager.sigma_kwargs
        sigma_start = param_class.kwargs2args(lens_sigma, source_sigma, lens_light_sigma, ps_sigma, cosmo_sigma)
        num_param, param_list = param_class.num_param()
        # run MCMC
        if not init_samples is None and re_use_samples is True:
            print("test that you are here!")
            num_samples, num_param_prev = np.shape(init_samples)
            print(num_samples, num_param_prev, num_param, 'shape of init_sample')
            if num_param_prev == num_param:
                print("re-using previous samples to initialize the next MCMC run.")
                initpos = ReusePositionGenerator(init_samples)
            else:
                print("Can not re-use previous MCMC samples due to change in option")
                initpos = None
        else:
            initpos = None
        samples, dist = mcmc_class.mcmc_CH(walkerRatio, n_run, n_burn, mean_start, np.array(sigma_start) * sigma_scale,
                                           threadCount=threadCount,
                                           mpi=self._mpi, init_pos=initpos)
        return samples, param_list, dist

Response: This routine runs the MCMC routine.