Instruction:
How would you explain what the following Python 3 function does
def pso(self, n_particles, n_iterations, sigma_scale=1, print_key='PSO', threadCount=1):

        param_class = self._param_class
        init_pos = 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)
        lowerLimit = np.array(init_pos) - np.array(sigma_start) * sigma_scale
        upperLimit = np.array(init_pos) + np.array(sigma_start) * sigma_scale
        num_param, param_list = param_class.num_param()

        # run PSO
        sampler = Sampler(likelihoodModule=self.likelihoodModule)
        result, chain = sampler.pso(n_particles, n_iterations, lowerLimit, upperLimit, init_pos=init_pos,
                                       threadCount=threadCount, mpi=self._mpi, print_key=print_key)
        lens_result, source_result, lens_light_result, ps_result, cosmo_result = param_class.args2kwargs(result,
                                                                                bijective=True)
        return lens_result, source_result, lens_light_result, ps_result, cosmo_result, chain, param_list

Response: This routine runs the PSO algorithm and returns the best fit parameter for each particle system.


Instruction:
Here you have a function in Python 3, explain what it does
def psf_iteration(self, num_iter=10, no_break=True, stacking_method='median', block_center_neighbour=0, keep_psf_error_map=True,
                 psf_symmetry=1, psf_iter_factor=1, verbose=True, compute_bands=None):
        """
        iterative PSF reconstruction

        :param num_iter: number of iterations in the process
        :param no_break: bool, if False will break the process as soon as one step lead to a wors reconstruction then the previous step
        :param stacking_method: string, 'median' and 'mean' supported
        :param block_center_neighbour: radius of neighbouring point source to be blocked in the reconstruction
        :param keep_psf_error_map: bool, whether or not to keep the previous psf_error_map
        :param psf_symmetry: int, number of invariant rotations in the reconstructed PSF
        :param psf_iter_factor: factor of new estimated PSF relative to the old one PSF_updated = (1-psf_iter_factor) * PSF_old + psf_iter_factor*PSF_new
        :param verbose: bool, print statements
        :param compute_bands: bool list, if multiple bands, this process can be limited to a subset of bands
        :return: 0, updated PSF is stored in self.mult_iband_list
        """
        #lens_temp = copy.deepcopy(lens_input)
        kwargs_model = self._updateManager.kwargs_model
        param_class = self._param_class
        lens_updated = param_class.update_lens_scaling(self._cosmo_temp, self._lens_temp)
        source_updated = param_class.image2source_plane(self._source_temp, lens_updated)
        if compute_bands is None:
            compute_bands = [True] * len(self.multi_band_list)

        for i in range(len(self.multi_band_list)):
            if compute_bands[i] is True:
                kwargs_data = self.multi_band_list[i][0]
                kwargs_psf = self.multi_band_list[i][1]
                kwargs_numerics = self.multi_band_list[i][2]
                image_model = class_creator.create_image_model(kwargs_data=kwargs_data,
                                                               kwargs_psf=kwargs_psf,
                                                               kwargs_numerics=kwargs_numerics,
                                                               kwargs_model=kwargs_model)
                psf_iter = PsfFitting(image_model_class=image_model)
                kwargs_psf = psf_iter.update_iterative(kwargs_psf, lens_updated, source_updated,
                                                       self._lens_light_temp, self._ps_temp, num_iter=num_iter,
                                                       no_break=no_break, stacking_method=stacking_method,
                                                       block_center_neighbour=block_center_neighbour,
                                                       keep_psf_error_map=keep_psf_error_map,
                 psf_symmetry=psf_symmetry, psf_iter_factor=psf_iter_factor, verbose=verbose)
                self.multi_band_list[i][1] = kwargs_psf
        return 0

Response: This function is used to update the PSF in a single iteration of the process.


Instruction:
How would you implement a function in Python 3 that
aligns the coordinate systems of different exposures within a fixed model parameterisation by executing a PSOAlignmentFitting function on the specified set of parameters.

Response:
def align_images(self, n_particles=10, n_iterations=10, lowerLimit=-0.2, upperLimit=0.2, threadCount=1,
                     compute_bands=None):
        """
        aligns the coordinate systems of different exposures within a fixed model parameterisation by executing a PSO
        with relative coordinate shifts as free parameters

        :param n_particles: number of particles in the Particle Swarm Optimization
        :param n_iterations: number of iterations in the optimization process
        :param lowerLimit: lower limit of relative shift
        :param upperLimit: upper limit of relative shift
        :param verbose: bool, print statements
        :param compute_bands: bool list, if multiple bands, this process can be limited to a subset of bands
        :return:
        """
        kwargs_model = self._updateManager.kwargs_model
        param_class = self._updateManager.param_class(self._lens_temp)
        lens_updated = param_class.update_lens_scaling(self._cosmo_temp, self._lens_temp)
        source_updated = param_class.image2source_plane(self._source_temp, lens_updated)
        if compute_bands is None:
            compute_bands = [True] * len(self.multi_band_list)

        for i in range(len(self.multi_band_list)):
            if compute_bands[i] is True:
                kwargs_data = self.multi_band_list[i][0]
                kwargs_psf = self.multi_band_list[i][1]
                kwargs_numerics = self.multi_band_list[i][2]
                alignmentFitting = AlignmentFitting(kwargs_data, kwargs_psf, kwargs_numerics, kwargs_model, lens_updated, source_updated,
                                                        self._lens_light_temp, self._ps_temp)

                kwargs_data, chain = alignmentFitting.pso(n_particles=n_particles, n_iterations=n_iterations,
                                                          lowerLimit=lowerLimit, upperLimit=upperLimit,
                                                          threadCount=threadCount, mpi=self._mpi,
                                                          print_key='Alignment fitting for band %s ...' % i)
                print('Align completed for band %s.' % i)
                print('ra_shift: %s,  dec_shift: %s' %(kwargs_data['ra_shift'], kwargs_data['dec_shift']))
                self.multi_band_list[i][0] = kwargs_data
        return 0


Instruction:
Write a Python 3 script to
update lenstronomy settings on the fly

Response:
def update_settings(self, kwargs_model={}, kwargs_constraints={}, kwargs_likelihood={}, lens_add_fixed=[],
                     source_add_fixed=[], lens_light_add_fixed=[], ps_add_fixed=[], cosmo_add_fixed=[], lens_remove_fixed=[],
                     source_remove_fixed=[], lens_light_remove_fixed=[], ps_remove_fixed=[], cosmo_remove_fixed=[],
                        change_source_lower_limit=None, change_source_upper_limit=None):
        """
        updates lenstronomy settings "on the fly"

        :param kwargs_model: kwargs, specified keyword arguments overwrite the existing ones
        :param kwargs_constraints: kwargs, specified keyword arguments overwrite the existing ones
        :param kwargs_likelihood: kwargs, specified keyword arguments overwrite the existing ones
        :param lens_add_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param source_add_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param lens_light_add_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param ps_add_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param cosmo_add_fixed: ['param1', 'param2',...]
        :param lens_remove_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param source_remove_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param lens_light_remove_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param ps_remove_fixed: [[i_model, ['param1', 'param2',...], [...]]
        :param cosmo_remove_fixed: ['param1', 'param2',...]
        :return: 0, the settings are overwritten for the next fitting step to come
        """
        self._updateManager.update_options(kwargs_model, kwargs_constraints, kwargs_likelihood)
        self._updateManager.update_fixed(self._lens_temp, self._source_temp, self._lens_light_temp, self._ps_temp,
                                         self._cosmo_temp, lens_add_fixed, source_add_fixed, lens_light_add_fixed,
                                         ps_add_fixed, cosmo_add_fixed, lens_remove_fixed, source_remove_fixed,
                                         lens_light_remove_fixed, ps_remove_fixed, cosmo_remove_fixed)
        self._updateManager.update_limits(change_source_lower_limit, change_source_upper_limit)
        return 0


Instruction:
Write a Python 3 script for
returning the parameter values given A C_D_inv d

Response:
def get_param_WLS(A, C_D_inv, d, inv_bool=True):
    """
    returns the parameter values given
    :param A: response matrix Nd x Ns (Nd = # data points, Ns = # parameters)
    :param C_D_inv: inverse covariance matrix of the data, Nd x Nd, diagonal form
    :param d: data array, 1-d Nd
    :param inv_bool: boolean, wheter returning also the inverse matrix or just solve the linear system
    :return: 1-d array of parameter values
    """
    M = A.T.dot(np.multiply(C_D_inv, A.T).T)
    if inv_bool:
        if np.linalg.cond(M) < 5/sys.float_info.epsilon:
            try:
                M_inv = np.linalg.inv(M)
            except:
                M_inv = np.zeros_like(M)
        else:
            M_inv = np.zeros_like(M)
        R = A.T.dot(np.multiply(C_D_inv, d))
        B = M_inv.dot(R)
    else:
        if np.linalg.cond(M) < 5/sys.float_info.epsilon:
            R = A.T.dot(np.multiply(C_D_inv, d))
            try:
                B = np.linalg.solve(M, R).T
            except:
                B = np.zeros(len(A.T))
        else:
            B = np.zeros(len(A.T))
        M_inv = None
    image = A.dot(B)
    return B, M_inv, image


Instruction:
Can you write a function in Python 3 where it
returns the anisotorpy parameter at a given radius

Response:
def beta_r(self, r, kwargs):
        """
        returns the anisotorpy parameter at a given radius
        :param r:
        :return:
        """
        if self._type == 'const':
            return self.const_beta(kwargs)
        elif self._type == 'OsipkovMerritt':
            return self.ospikov_meritt(r, kwargs)
        elif self._type == 'Colin':
            return self.colin(r, kwargs)
        elif self._type == 'isotropic':
            return self.isotropic()
        elif self._type == 'radial':
            return self.radial()
        else:
            raise ValueError('anisotropy type %s not supported!' % self._type)


Instruction:
Here you have a function in Python 3, explain what it does
def _B(self, x, a, b):
        return special.betainc(a, b, x) * special.beta(a, b)

Response: incomplete Beta function as described in Mamon & Lokas A13.


Instruction:
Implement a function in Python 3 to
return the anisotorpy parameter at a given radius

Response:
def beta_r(self, r, kwargs):
        """
        returns the anisotorpy parameter at a given radius
        :param r:
        :return:
        """
        if self._type == 'const':
            return self.const_beta(kwargs)
        elif self._type == 'r_ani':
            return self.beta_r_ani(r, kwargs)
        else:
            raise ValueError('anisotropy type %s not supported!' % self._type)


Instruction:
Implement a function in Python 3 to
create a Data instance of lenstronomy based on knowledge of the observation

Response:
def data_class(self):
        """
        creates a Data() instance of lenstronomy based on knowledge of the observation

        :return: instance of Data() class
        """
        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=self.numpix, deltapix=self.pixel_scale, subgrid_res=1, left_lower=False, inverse=False)
        kwargs_data = {'numPix': self.numpix, 'ra_at_xy_0': ra_at_xy_0, 'dec_at_xy_0': dec_at_xy_0,
                       'transform_pix2angle': Mpix2coord,
                       'background_rms': self.background_noise,
                       'exp_time': self.scaled_exposure_time}
        data_class = Data(kwargs_data)
        return data_class


Instruction:
Can you generate a brief explanation for the following Python 3 code
def psf_class(self):
        if self._psf_type == 'GAUSSIAN':
            psf_type = "GAUSSIAN"
            fwhm = self._seeing
            kwargs_psf = {'psf_type': psf_type, 'fwhm': fwhm}
        elif self._psf_type == 'PIXEL':
            if self._psf_model is not None:
                kwargs_psf = {'psf_type': "PIXEL", 'kernel_point_source': self._psf_model}
            else:
                raise ValueError("You need to create the class instance with a psf_model!")
        else:
            raise ValueError("psf_type %s not supported!" % self._psf_type)
        psf_class = PSF(kwargs_psf)
        return psf_class

Response: Creates an instance of the PSF class based on knowledge of the observations.


Instruction:
Make a summary of the following Python 3 code
def update_options(self, kwargs_model, kwargs_constraints, kwargs_likelihood):
        kwargs_model_updated = self.kwargs_model.update(kwargs_model)
        kwargs_constraints_updated = self.kwargs_constraints.update(kwargs_constraints)
        kwargs_likelihood_updated = self.kwargs_likelihood.update(kwargs_likelihood)
        return kwargs_model_updated, kwargs_constraints_updated, kwargs_likelihood_updated

Response: Updates the kwargs_model kwargs_constraints and kwargs_likelihood by updating the kwargs_model and kwargs_constraints and kwargs_likelihood.


Instruction:
Can you generate the documentation for the following Python 3 function
def update_limits(self, change_source_lower_limit=None, change_source_upper_limit=None):
        if not change_source_lower_limit is None:
            self._source_lower = self._update_limit(change_source_lower_limit, self._source_lower)
        if not change_source_upper_limit is None:
            self._source_upper = self._update_limit(change_source_upper_limit, self._source_upper)

Response: Updates the limits of the internal state of the source instance.


Instruction:
Create a Python 3 function for
updating the kwargs fixed with the values of the keyword arguments that are stated in _add_fixed to the existing kwargs fixed.

Response:
def update_fixed(self, kwargs_lens, kwargs_source, kwargs_lens_light, kwargs_ps, kwargs_cosmo, lens_add_fixed=[],
                     source_add_fixed=[], lens_light_add_fixed=[], ps_add_fixed=[], cosmo_add_fixed=[], lens_remove_fixed=[],
                     source_remove_fixed=[], lens_light_remove_fixed=[], ps_remove_fixed=[], cosmo_remove_fixed=[]):
        """
        adds the values of the keyword arguments that are stated in the _add_fixed to the existing fixed arguments.

        :param kwargs_lens:
        :param kwargs_source:
        :param kwargs_lens_light:
        :param kwargs_ps:
        :param kwargs_cosmo:
        :param lens_add_fixed:
        :param source_add_fixed:
        :param lens_light_add_fixed:
        :param ps_add_fixed:
        :param cosmo_add_fixed:
        :return: updated kwargs fixed
        """
        lens_fixed = self._add_fixed(kwargs_lens, self._lens_fixed, lens_add_fixed)
        lens_fixed = self._remove_fixed(lens_fixed, lens_remove_fixed)
        source_fixed = self._add_fixed(kwargs_source, self._source_fixed, source_add_fixed)
        source_fixed = self._remove_fixed(source_fixed, source_remove_fixed)
        lens_light_fixed = self._add_fixed(kwargs_lens_light, self._lens_light_fixed, lens_light_add_fixed)
        lens_light_fixed = self._remove_fixed(lens_light_fixed, lens_light_remove_fixed)
        ps_fixed = self._add_fixed(kwargs_ps, self._ps_fixed, ps_add_fixed)
        ps_fixed = self._remove_fixed(ps_fixed, ps_remove_fixed)
        cosmo_fixed = copy.deepcopy(self._cosmo_fixed)
        for param_name in cosmo_add_fixed:
            if param_name in cosmo_fixed:
                pass
            else:
                cosmo_fixed[param_name] = kwargs_cosmo[param_name]
        for param_name in cosmo_remove_fixed:
            if param_name in cosmo_fixed:
                del cosmo_fixed[param_name]
                self._lens_fixed, self._source_fixed, self._lens_light_fixed, self._ps_fixed, self._cosmo_fixed = lens_fixed, source_fixed, lens_light_fixed, ps_fixed, cosmo_fixed


Instruction:
Implement a Python 3 function for
calculating the average LOS integrated velocity dispersion in the slit

Response:
def vel_disp(self, gamma, theta_E, r_eff, r_ani, R_slit, dR_slit, FWHM, rendering_number=1000):
        """
        computes the averaged LOS velocity dispersion in the slit (convolved)

        :param gamma: power-law slope of the mass profile (isothermal = 2)
        :param theta_E: Einstein radius of the lens (in arcseconds)
        :param r_eff: half light radius of the Hernquist profile (or as an approximation of any other profile to be described as a Hernquist profile
        :param r_ani: anisotropy radius
        :param R_slit: length of the slit/box
        :param dR_slit: width of the slit/box
        :param FWHM: full width at half maximum of the seeing conditions, described as a Gaussian
        :param rendering_number: number of spectral renderings drawn from the light distribution that go through the
            slit of the observations

        :return: LOS integrated velocity dispersion in units [km/s]
        """
        sigma_s2_sum = 0
        rho0_r0_gamma = self._rho0_r0_gamma(theta_E, gamma)
        for i in range(0, rendering_number):
            sigma_s2_draw = self.vel_disp_one(gamma, rho0_r0_gamma, r_eff, r_ani, R_slit, dR_slit, FWHM)
            sigma_s2_sum += sigma_s2_draw
        sigma_s2_average = sigma_s2_sum / rendering_number
        return np.sqrt(sigma_s2_average)


Instruction:
Here you have a function in Python 3, explain what it does
def vel_disp_one(self, gamma, rho0_r0_gamma, r_eff, r_ani, R_slit, dR_slit, FWHM):
        a = 0.551 * r_eff
        while True:
            r = self.P_r(a)  # draw r
            R, x, y = self.R_r(r)  # draw projected R
            x_, y_ = self.displace_PSF(x, y, FWHM)  # displace via PSF
            bool = self.check_in_slit(x_, y_, R_slit, dR_slit)
            if bool is True:
                break
        sigma_s2 = self.sigma_s2(r, R, r_ani, a, gamma, rho0_r0_gamma)
        return sigma_s2

Response: Compute one realisation of the velocity dispersion realized in the potential


Instruction:
Write a Python 3 script for
drawing a random projection from radius r in 2d and 1d radius draws a random projection from radius r in 2d and 1d radius

Response:
def R_r(self, r):
        """
        draws a random projection from radius r in 2d and 1d
        :param r: 3d radius
        :return: R, x, y
        """
        phi = np.random.uniform(0, 2*np.pi)
        theta = np.random.uniform(0, np.pi)
        x = r * np.sin(theta) * np.cos(phi)
        y = r * np.sin(theta) * np.sin(phi)
        R = np.sqrt(x**2 + y**2)
        return R, x, y


Instruction:
Can you tell what is the following Python 3 function doing
def sigma_s2(self, r, R, r_ani, a, gamma, rho0_r0_gamma):
        beta = self._beta_ani(r, r_ani)
        return (1 - beta * R**2/r**2) * self.sigma_r2(r, a, gamma, rho0_r0_gamma, r_ani)

Response: calculate sigma_s2 for a given projected velocity dispersion


Instruction:
How would you explain what the following Python 3 function does
def sigma_r2(self, r, a, gamma, rho0_r0_gamma, r_ani):
        # first term
        prefac1 = 4*np.pi * const.G * a**(-gamma) * rho0_r0_gamma / (3-gamma)
        prefac2 = r * (r + a)**3/(r**2 + r_ani**2)
        hyp1 = vel_util.hyp_2F1(a=2+gamma, b=gamma, c=3+gamma, z=1./(1+r/a))
        hyp2 = vel_util.hyp_2F1(a=3, b=gamma, c=1+gamma, z=-a/r)
        fac = r_ani**2/a**2 * hyp1 / ((2+gamma) * (r/a + 1)**(2+gamma)) + hyp2 / (gamma*(r/a)**gamma)
        return prefac1 * prefac2 * fac * (self._cosmo.arcsec2phys_lens(1.) * const.Mpc / 1000) ** 2

Response: calculate sigma of an object


Instruction:
Create a Python 3 function for
making sure that the window covers all the light, otherwise the moments may give to low answers. :param kwargs_lens_light: :param center_x: :param center_y: :param model_bool_list: :param deltaPix: :param numPix: :return:

Response:
def ellipticity_lens_light(self, kwargs_lens_light, center_x=0, center_y=0, model_bool_list=None, deltaPix=None,
                               numPix=None):
        """
        make sure that the window covers all the light, otherwise the moments may give to low answers.

        :param kwargs_lens_light:
        :param center_x:
        :param center_y:
        :param model_bool_list:
        :param deltaPix:
        :param numPix:
        :return:
        """
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens_light)
        if numPix is None:
            numPix = 100
        if deltaPix is None:
            deltaPix = 0.05
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x
        y_grid += center_y
        I_xy = self._lens_light_internal(x_grid, y_grid, kwargs_lens_light, model_bool_list=model_bool_list)
        e1, e2 = analysis_util.ellipticities(I_xy, x_grid, y_grid)
        return e1, e2


Instruction:
Make a summary of the following Python 3 code
def half_light_radius_lens(self, kwargs_lens_light, center_x=0, center_y=0, model_bool_list=None, deltaPix=None, numPix=None):
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens_light)
        if numPix is None:
            numPix = 1000
        if deltaPix is None:
            deltaPix = 0.05
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x
        y_grid += center_y
        lens_light = self._lens_light_internal(x_grid, y_grid, kwargs_lens_light, model_bool_list=model_bool_list)
        R_h = analysis_util.half_light_radius(lens_light, x_grid, y_grid, center_x, center_y)
        return R_h

Response: Calculates the half - light - radius of the deflector light and the total photon flux.


Instruction:
Here you have a function in Python 3, explain what it does
def half_light_radius_source(self, kwargs_source, center_x=0, center_y=0, deltaPix=None, numPix=None):
        if numPix is None:
            numPix = 1000
        if deltaPix is None:
            deltaPix = 0.005
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x
        y_grid += center_y
        source_light = self.SourceModel.surface_brightness(x_grid, y_grid, kwargs_source)
        R_h = analysis_util.half_light_radius(source_light, x_grid, y_grid, center_x=center_x, center_y=center_y)
        return R_h

Response: Calculates the half - light - radius of the deflector light and the total photon flux.


Instruction:
Can you generate the documentation for the following Python 3 function
def _lens_light_internal(self, x_grid, y_grid, kwargs_lens_light, model_bool_list=None):
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens_light)
        lens_light = np.zeros_like(x_grid)
        for i, bool in enumerate(model_bool_list):
            if bool is True:
                lens_light_i = self.LensLightModel.surface_brightness(x_grid, y_grid, kwargs_lens_light, k=i)
                lens_light += lens_light_i
        return lens_light

Response: Compute the lens light for each entry in the list of model_bool_list


Instruction:
Can you generate the documentation for the following Python 3 function
def multi_gaussian_lens_light(self, kwargs_lens_light, model_bool_list=None, e1=0, e2=0, n_comp=20, deltaPix=None, numPix=None):
        if 'center_x' in kwargs_lens_light[0]:
            center_x = kwargs_lens_light[0]['center_x']
            center_y = kwargs_lens_light[0]['center_y']
        else:
            center_x, center_y = 0, 0
        r_h = self.half_light_radius_lens(kwargs_lens_light, center_x=center_x, center_y=center_y,
                                          model_bool_list=model_bool_list, deltaPix=deltaPix, numPix=numPix)
        r_array = np.logspace(-3, 2, 200) * r_h * 2
        x_coords, y_coords = param_util.transform_e1e2(r_array, np.zeros_like(r_array), e1=-e1, e2=-e2)
        x_coords += center_x
        y_coords += center_y
        #r_array = np.logspace(-2, 1, 50) * r_h
        flux_r = self._lens_light_internal(x_coords, y_coords, kwargs_lens_light,
                                           model_bool_list=model_bool_list)
        amplitudes, sigmas, norm = mge.mge_1d(r_array, flux_r, N=n_comp)
        return amplitudes, sigmas, center_x, center_y

Response: This function computes the multi - Gaussian decomposition of the lens light profile.


Instruction:
How would you explain what the following Python 3 function does
def multi_gaussian_lens(self, kwargs_lens, model_bool_list=None, e1=0, e2=0, n_comp=20):
        if 'center_x' in kwargs_lens[0]:
            center_x = kwargs_lens[0]['center_x']
            center_y = kwargs_lens[0]['center_y']
        else:
            raise ValueError('no keyword center_x defined!')
        theta_E = self._lensModelExtensions.effective_einstein_radius(kwargs_lens)
        r_array = np.logspace(-4, 2, 200) * theta_E
        x_coords, y_coords = param_util.transform_e1e2(r_array, np.zeros_like(r_array), e1=-e1, e2=-e2)
        x_coords += center_x
        y_coords += center_y
        #r_array = np.logspace(-2, 1, 50) * theta_E
        if model_bool_list is None:
            model_bool_list = [True] * len(kwargs_lens)
        kappa_s = np.zeros_like(r_array)
        for i in range(len(kwargs_lens)):
            if model_bool_list[i] is True:
                kappa_s += self.LensModel.kappa(x_coords, y_coords, kwargs_lens, k=i)
        amplitudes, sigmas, norm = mge.mge_1d(r_array, kappa_s, N=n_comp)
        return amplitudes, sigmas, center_x, center_y

Response: This function computes the amplitudes and sigmas of a multi - Gaussian lens model in convergence space.


Instruction:
Here you have a function in Python 3, explain what it does
def flux_components(self, kwargs_light, n_grid=400, delta_grid=0.01, deltaPix=0.05, type="lens"):
        flux_list = []
        R_h_list = []
        x_grid, y_grid = util.make_grid(numPix=n_grid, deltapix=delta_grid)
        kwargs_copy = copy.deepcopy(kwargs_light)
        for k, kwargs in enumerate(kwargs_light):
            if 'center_x' in kwargs_copy[k]:
                kwargs_copy[k]['center_x'] = 0
                kwargs_copy[k]['center_y'] = 0
            if type == 'lens':
                light = self.LensLightModel.surface_brightness(x_grid, y_grid, kwargs_copy, k=k)
            elif type == 'source':
                light = self.SourceModel.surface_brightness(x_grid, y_grid, kwargs_copy, k=k)
            else:
                raise ValueError("type %s not supported!" % type)
            flux = np.sum(light)*delta_grid**2 / deltaPix**2
            R_h = analysis_util.half_light_radius(light, x_grid, y_grid)
            flux_list.append(flux)
            R_h_list.append(R_h)
        return flux_list, R_h_list

Response: computes the total flux in each component of the model


Instruction:
Implement a Python 3 function for
computing the error map for a source model

Response:
def error_map_source(self, kwargs_source, x_grid, y_grid, cov_param):
        """
        variance of the linear source reconstruction in the source plane coordinates,
        computed by the diagonal elements of the covariance matrix of the source reconstruction as a sum of the errors
        of the basis set.

        :param kwargs_source: keyword arguments of source model
        :param x_grid: x-axis of positions to compute error map
        :param y_grid: y-axis of positions to compute error map
        :param cov_param: covariance matrix of liner inversion parameters
        :return: diagonal covariance errors at the positions (x_grid, y_grid)
        """

        error_map = np.zeros_like(x_grid)
        basis_functions, n_source = self.SourceModel.functions_split(x_grid, y_grid, kwargs_source)
        basis_functions = np.array(basis_functions)

        if cov_param is not None:
            for i in range(len(error_map)):
                error_map[i] = basis_functions[:, i].T.dot(cov_param[:n_source, :n_source]).dot(basis_functions[:, i])
        return error_map


Instruction:
Write a Python 3 script for
taking a lens light model and turns it numerically in a lens model (with all lensmodel quantities computed on a grid). Then provides an interpolated grid for the quantities. :param kwargs_lens_light: lens light keyword argument list :param numPix: number of pixels per axis for the return interpolation :param deltaPix: interpolation/pixel size :param center_x: center of the grid :param center_y: center of the grid :param subgrid: subgrid for the numerical integrals :return:

Response:
def light2mass_interpol(lens_light_model_list, kwargs_lens_light, numPix=100, deltaPix=0.05, subgrid_res=5, center_x=0, center_y=0):
        """
        takes a lens light model and turns it numerically in a lens model
        (with all lensmodel quantities computed on a grid). Then provides an interpolated grid for the quantities.

        :param kwargs_lens_light: lens light keyword argument list
        :param numPix: number of pixels per axis for the return interpolation
        :param deltaPix: interpolation/pixel size
        :param center_x: center of the grid
        :param center_y: center of the grid
        :param subgrid: subgrid for the numerical integrals
        :return:
        """
        # make sugrid
        x_grid_sub, y_grid_sub = util.make_grid(numPix=numPix*5, deltapix=deltaPix, subgrid_res=subgrid_res)
        import lenstronomy.Util.mask as mask_util
        mask = mask_util.mask_sphere(x_grid_sub, y_grid_sub, center_x, center_y, r=1)
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        # compute light on the subgrid
        lightModel = LightModel(light_model_list=lens_light_model_list)
        flux = lightModel.surface_brightness(x_grid_sub, y_grid_sub, kwargs_lens_light)
        flux_norm = np.sum(flux[mask == 1]) / np.sum(mask)
        flux /= flux_norm
        from lenstronomy.LensModel.numerical_profile_integrals import ConvergenceIntegrals
        integral = ConvergenceIntegrals()

        # compute lensing quantities with subgrid
        convergence_sub = flux
        f_x_sub, f_y_sub = integral.deflection_from_kappa(convergence_sub, x_grid_sub, y_grid_sub,
                                                          deltaPix=deltaPix/float(subgrid_res))
        f_sub = integral.potential_from_kappa(convergence_sub, x_grid_sub, y_grid_sub,
                                                          deltaPix=deltaPix/float(subgrid_res))
        # interpolation function on lensing quantities
        x_axes_sub, y_axes_sub = util.get_axes(x_grid_sub, y_grid_sub)
        from lenstronomy.LensModel.Profiles.interpol import Interpol
        interp_func = Interpol()
        interp_func.do_interp(x_axes_sub, y_axes_sub, f_sub, f_x_sub, f_y_sub)
        # compute lensing quantities on sparser grid
        x_axes, y_axes = util.get_axes(x_grid, y_grid)
        f_ = interp_func.function(x_grid, y_grid)
        f_x, f_y = interp_func.derivatives(x_grid, y_grid)
        # numerical differentials for second order differentials
        from lenstronomy.LensModel.numeric_lens_differentials import NumericLens
        lens_differential = NumericLens(lens_model_list=['INTERPOL'])
        kwargs = [{'grid_interp_x': x_axes_sub, 'grid_interp_y': y_axes_sub, 'f_': f_sub,
                   'f_x': f_x_sub, 'f_y': f_y_sub}]
        f_xx, f_xy, f_yx, f_yy = lens_differential.hessian(x_grid, y_grid, kwargs)
        kwargs_interpol = {'grid_interp_x': x_axes, 'grid_interp_y': y_axes, 'f_': util.array2image(f_),
                   'f_x': util.array2image(f_x), 'f_y': util.array2image(f_y), 'f_xx': util.array2image(f_xx),
                           'f_xy': util.array2image(f_xy), 'f_yy': util.array2image(f_yy)}
        return kwargs_interpol


Instruction:
Make a summary of the following Python 3 code
def mass_fraction_within_radius(self, kwargs_lens, center_x, center_y, theta_E, numPix=100):
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=2.*theta_E / numPix)
        x_grid += center_x
        y_grid += center_y
        mask = mask_util.mask_sphere(x_grid, y_grid, center_x, center_y, theta_E)
        kappa_list = []
        for i in range(len(kwargs_lens)):
            kappa = self.LensModel.kappa(x_grid, y_grid, kwargs_lens, k=i)
            kappa_mean = np.sum(kappa * mask) / np.sum(mask)
            kappa_list.append(kappa_mean)
        return kappa_list

Response: computes the mean convergence of all the different lens model components within a spherical aperture


Instruction:
Create a Python 3 function to
update the search area for the lens equation solver

Response:
def update_search_window(self, search_window, x_center, y_center):
        """
        update the search area for the lens equation solver

        :param search_window: search_window: window size of the image position search with the lens equation solver.
        :param x_center: center of search window
        :param y_center: center of search window
        :return: updated self instances
        """
        self._search_window, self._x_center, self._y_center = search_window, x_center, y_center


Instruction:
Can you generate a brief explanation for the following Python 3 code
def point_source_list(self, kwargs_ps, kwargs_lens, k=None):
        ra_list, dec_list = self.image_position(kwargs_ps, kwargs_lens, k=k)
        amp_list = self.image_amplitude(kwargs_ps, kwargs_lens)
        ra_array, dec_array, amp_array = [], [], []
        for i, ra in enumerate(ra_list):
            for j in range(len(ra)):
                ra_array.append(ra_list[i][j])
                dec_array.append(dec_list[i][j])
                amp_array.append(amp_list[i][j])
        return ra_array, dec_array, amp_array

Response: returns the coordinates and amplitudes of all point sources in a single array


Instruction:
Implement a Python 3 function for
returning the image amplitudes of the point sources

Response:
def image_amplitude(self, kwargs_ps, kwargs_lens, k=None):
        """
        returns the image amplitudes

        :param kwargs_ps:
        :param kwargs_lens:
        :return:
        """
        amp_list = []
        for i, model in enumerate(self._point_source_list):
            if k is None or k == i:
                amp_list.append(model.image_amplitude(kwargs_ps=kwargs_ps[i], kwargs_lens=kwargs_lens, min_distance=self._min_distance,
                                                        search_window=self._search_window,
                                                        precision_limit=self._precision_limit,
                                                        num_iter_max=self._num_iter_max, x_center=self._x_center,
                                                        y_center=self._y_center))
        return amp_list


Instruction:
Create a Python 3 function to
return the source amplitudes of the current set of points

Response:
def source_amplitude(self, kwargs_ps, kwargs_lens):
        """
        returns the source amplitudes

        :param kwargs_ps:
        :param kwargs_lens:
        :return:
        """
        amp_list = []
        for i, model in enumerate(self._point_source_list):
            amp_list.append(model.source_amplitude(kwargs_ps=kwargs_ps[i], kwargs_lens=kwargs_lens))
        return amp_list


Instruction:
Can you tell what is the following Python 3 function doing
def check_image_positions(self, kwargs_ps, kwargs_lens, tolerance=0.001):
        x_image_list, y_image_list = self.image_position(kwargs_ps, kwargs_lens)
        for i, model in enumerate(self._point_source_list):
            if model in ['LENSED_POSITION', 'SOURCE_POSITION']:
                x_pos = x_image_list[i]
                y_pos = y_image_list[i]
                x_source, y_source = self._lensModel.ray_shooting(x_pos, y_pos, kwargs_lens)
                dist = np.sqrt((x_source - x_source[0]) ** 2 + (y_source - y_source[0]) ** 2)
                if np.max(dist) > tolerance:
                    return False
        return True

Response: checks whether the point sources in kwargs_ps satisfy the lens equation with a tolerance


Instruction:
Create a Python 3 function to
compute the finite magnification of an extended source with Gaussian light profile.

Response:
def magnification_finite(self, x_pos, y_pos, kwargs_lens, source_sigma=0.003, window_size=0.1, grid_number=100,
                             shape="GAUSSIAN", polar_grid=False, aspect_ratio=0.5):
        """
        returns the magnification of an extended source with Gaussian light profile
        :param x_pos: x-axis positons of point sources
        :param y_pos: y-axis position of point sources
        :param kwargs_lens: lens model kwargs
        :param source_sigma: Gaussian sigma in arc sec in source
        :param window_size: size of window to compute the finite flux
        :param grid_number: number of grid cells per axis in the window to numerically comute the flux
        :return: numerically computed brightness of the sources
        """

        mag_finite = np.zeros_like(x_pos)
        deltaPix = float(window_size)/grid_number
        if shape == 'GAUSSIAN':
            from lenstronomy.LightModel.Profiles.gaussian import Gaussian
            quasar = Gaussian()
        elif shape == 'TORUS':
            import lenstronomy.LightModel.Profiles.torus as quasar
        else:
            raise ValueError("shape %s not valid for finite magnification computation!" % shape)
        x_grid, y_grid = util.make_grid(numPix=grid_number, deltapix=deltaPix, subgrid_res=1)

        if polar_grid:
            a = window_size*0.5
            b = window_size*0.5*aspect_ratio
            ellipse_inds = (x_grid*a**-1) **2 + (y_grid*b**-1) **2 <= 1
            x_grid, y_grid = x_grid[ellipse_inds], y_grid[ellipse_inds]

        for i in range(len(x_pos)):
            ra, dec = x_pos[i], y_pos[i]

            center_x, center_y = self._lensModel.ray_shooting(ra, dec, kwargs_lens)

            if polar_grid:
                theta = np.arctan2(dec,ra)
                xcoord, ycoord = util.rotate(x_grid, y_grid, theta)
            else:
                xcoord, ycoord = x_grid, y_grid

            betax, betay = self._lensModel.ray_shooting(xcoord + ra, ycoord + dec, kwargs_lens)

            I_image = quasar.function(betax, betay, 1., source_sigma, source_sigma, center_x, center_y)
            mag_finite[i] = np.sum(I_image) * deltaPix**2

        return mag_finite


Instruction:
Here you have a function in Python 3, explain what it does
def _tiling_crit(self, edge1, edge2, edge_90, max_order, kwargs_lens):
        ra_1, dec_1, mag_1 = edge1
        ra_2, dec_2, mag_2 = edge2
        ra_3, dec_3, mag_3 = edge_90
        sign_list = np.sign([mag_1, mag_2, mag_3])
        if sign_list[0] == sign_list[1] and sign_list[0] == sign_list[2]:  # if all signs are the same
            return [], []
        else:
            # split triangle along the long axis
            # execute tiling twice
            # add ra_crit and dec_crit together
            # if max depth has been reached, return the mean value in the triangle
            max_order -= 1
            if max_order <= 0:
                return [(ra_1 + ra_2 + ra_3)/3], [(dec_1 + dec_2 + dec_3)/3]
            else:
                # split triangle
                ra_90_ = (ra_1 + ra_2)/2  # find point in the middle of the long axis to split triangle
                dec_90_ = (dec_1 + dec_2)/2
                mag_90_ = self._lensModel.magnification(ra_90_, dec_90_, kwargs_lens)
                edge_90_ = [ra_90_, dec_90_, mag_90_]
                ra_crit, dec_crit = self._tiling_crit(edge1=edge_90, edge2=edge1, edge_90=edge_90_, max_order=max_order,
                                                      kwargs_lens=kwargs_lens)
                ra_crit_2, dec_crit_2 = self._tiling_crit(edge1=edge_90, edge2=edge2, edge_90=edge_90_, max_order=max_order,
                                                          kwargs_lens=kwargs_lens)
                ra_crit += ra_crit_2
                dec_crit += dec_crit_2
                return ra_crit, dec_crit

Response: tiling a rectangular triangle and compares the signs of the magnification


Instruction:
Write a Python 3 script for
computing the radius of the effective Einstein radius estimate

Response:
def effective_einstein_radius(self, kwargs_lens_list, k=None, spacing=1000):
        """
        computes the radius with mean convergence=1

        :param kwargs_lens:
        :param spacing: number of annular bins to compute the convergence (resolution of the Einstein radius estimate)
        :return:
        """
        if 'center_x' in kwargs_lens_list[0]:
            center_x = kwargs_lens_list[0]['center_x']
            center_y = kwargs_lens_list[0]['center_y']
        elif self._lensModel.lens_model_list[0] in ['INTERPOL', 'INTERPOL_SCALED']:
            center_x, center_y = 0, 0
        else:
            center_x, center_y = 0, 0
        numPix = 200
        deltaPix = 0.05
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x
        y_grid += center_y
        kappa = self._lensModel.kappa(x_grid, y_grid, kwargs_lens_list, k=k)
        if self._lensModel.lens_model_list[0] in ['INTERPOL', 'INTERPOL_SCALED']:
            center_x = x_grid[kappa == np.max(kappa)]
            center_y = y_grid[kappa == np.max(kappa)]
        kappa = util.array2image(kappa)
        r_array = np.linspace(0.0001, numPix*deltaPix/2., spacing)
        for r in r_array:
            mask = np.array(1 - mask_util.mask_center_2d(center_x, center_y, r, x_grid, y_grid))
            sum_mask = np.sum(mask)
            if sum_mask > 0:
                kappa_mean = np.sum(kappa*mask)/np.sum(mask)
                if kappa_mean < 1:
                    return r
        print(kwargs_lens_list, "Warning, no Einstein radius computed!")
        return r_array[-1]


Instruction:
Can you generate a brief explanation for the following Python 3 code
def external_lensing_effect(self, kwargs_lens, lens_model_internal_bool=None):
        alpha0_x, alpha0_y = 0, 0
        kappa_ext = 0
        shear1, shear2 = 0, 0
        if lens_model_internal_bool is None:
            lens_model_internal_bool = [True] * len(kwargs_lens)
        for i, kwargs in enumerate(kwargs_lens):
            if not lens_model_internal_bool[i] is True:
                f_x, f_y = self._lensModel.alpha(0, 0, kwargs_lens, k=i)
                f_xx, f_xy, f_yx, f_yy = self._lensModel.hessian(0, 0, kwargs_lens, k=i)
                alpha0_x += f_x
                alpha0_y += f_y
                kappa_ext += (f_xx + f_yy)/2.
                shear1 += 1./2 * (f_xx - f_yy)
                shear2 += f_xy
        return alpha0_x, alpha0_y, kappa_ext, shear1, shear2

Response: computes the external deflection shear and convergence at ( 0 0


Instruction:
How would you explain what the following Python 3 function does
def lens_center(self, kwargs_lens, k=None, bool_list=None, numPix=200, deltaPix=0.01, center_x_init=0, center_y_init=0):
        x_grid, y_grid = util.make_grid(numPix=numPix, deltapix=deltaPix)
        x_grid += center_x_init
        y_grid += center_y_init

        if bool_list is None:
            kappa = self._lensModel.kappa(x_grid, y_grid, kwargs_lens, k=k)
        else:
            kappa = np.zeros_like(x_grid)
            for k in range(len(kwargs_lens)):
                if bool_list[k] is True:
                    kappa += self._lensModel.kappa(x_grid, y_grid, kwargs_lens, k=k)
        center_x = x_grid[kappa == np.max(kappa)]
        center_y = y_grid[kappa == np.max(kappa)]
        return center_x, center_y

Response: computes convergence weighted center of a lens model


Instruction:
Write a Python 3 script to
compute the logarithmic power - law slope of a profile

Response:
def profile_slope(self, kwargs_lens_list, lens_model_internal_bool=None, num_points=10):
        """
        computes the logarithmic power-law slope of a profile

        :param kwargs_lens_list: lens model keyword argument list
        :param lens_model_internal_bool: bool list, indicate which part of the model to consider
        :param num_points: number of estimates around the Einstein radius
        :return:
        """
        theta_E = self.effective_einstein_radius(kwargs_lens_list)
        x0 = kwargs_lens_list[0]['center_x']
        y0 = kwargs_lens_list[0]['center_y']
        x, y = util.points_on_circle(theta_E, num_points)
        dr = 0.01
        x_dr, y_dr = util.points_on_circle(theta_E + dr, num_points)
        if lens_model_internal_bool is None:
            lens_model_internal_bool = [True]*len(kwargs_lens_list)

        alpha_E_x_i, alpha_E_y_i = self._lensModel.alpha(x0 + x, y0 + y, kwargs_lens_list, k=lens_model_internal_bool)
        alpha_E_r = np.sqrt(alpha_E_x_i**2 + alpha_E_y_i**2)
        alpha_E_dr_x_i, alpha_E_dr_y_i = self._lensModel.alpha(x0 + x_dr, y0 + y_dr, kwargs_lens_list,
                                                               k=lens_model_internal_bool)
        alpha_E_dr = np.sqrt(alpha_E_dr_x_i ** 2 + alpha_E_dr_y_i ** 2)
        slope = np.mean(np.log(alpha_E_dr / alpha_E_r) / np.log((theta_E + dr) / theta_E))
        gamma = -slope + 2
        return gamma


Instruction:
Can you generate the documentation for the following Python 3 function
def kappa(self, x, y, kwargs, diff=diff):
        f_xx, f_xy, f_yx, f_yy = self.hessian(x, y, kwargs, diff=diff)
        kappa = 1./2 * (f_xx + f_yy)
        return kappa

Response:
computes the convergence
        :return: kappa


Instruction:
Explain what the following Python 3 code does
def gamma(self, x, y, kwargs, diff=diff):
        f_xx, f_xy, f_yx, f_yy = self.hessian(x, y, kwargs, diff=diff)
        gamma1 = 1./2 * (f_xx - f_yy)
        gamma2 = f_xy
        return gamma1, gamma2

Response: computes the shear gamma


Instruction:
Can you generate the documentation for the following Python 3 function
def magnification(self, x, y, kwargs, diff=diff):
        f_xx, f_xy, f_yx, f_yy = self.hessian(x, y, kwargs, diff=diff)
        det_A = (1 - f_xx) * (1 - f_yy) - f_xy*f_yx
        return 1/det_A

Response: computes the magnification of the potential species


Instruction:
Can you generate the documentation for the following Python 3 function
def hessian(self, x, y, kwargs, diff=diff):
        alpha_ra, alpha_dec = self.alpha(x, y, kwargs)

        alpha_ra_dx, alpha_dec_dx = self.alpha(x + diff, y, kwargs)
        alpha_ra_dy, alpha_dec_dy = self.alpha(x, y + diff, kwargs)

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

        f_xx = dalpha_rara
        f_yy = dalpha_decdec
        f_xy = dalpha_radec
        f_yx = dalpha_decra
        return f_xx, f_xy, f_yx, f_yy

Response: computes the differentials f_xx f_yy f_yx f_yy from f_x and f_ycluster.


Instruction:
Can you write a function in Python 3 where it
times - delay distance in units of Mpc

Response:
def D_dt(self, z_lens, z_source):
        """
        time-delay distance

        :param z_lens: redshift of lens
        :param z_source: redshift of source
        :return: time-delay distance in units of Mpc
        """
        return self.D_xy(0, z_lens) * self.D_xy(0, z_source) / self.D_xy(z_lens, z_source) * (1 + z_lens)


Instruction:
Given the following Python 3 function, write the documentation
def rho_crit(self):
        h = self.cosmo.H(0).value / 100.
        return 3 * h ** 2 / (8 * np.pi * const.G) * 10 ** 10 * const.Mpc / const.M_sun

Response: return value in M_sol or Mpc^3


Instruction:
Write a Python 3 script to
compute the Hermite polynomial for the given value x

Response:
def hermval(self, x, n_array, tensor=True):
        """
        computes the Hermit polynomial as numpy.polynomial.hermite.hermval
        difference: for values more than sqrt(n_max + 1) * cut_scale, the value is set to zero
        this should be faster and numerically stable

        :param x: array of values
        :param n_array: list of coeffs in H_n
        :param cut_scale: scale where the polynomial will be set to zero
        :return: see numpy.polynomial.hermite.hermval
        """
        if not self._stable_cut:
            return hermite.hermval(x, n_array)
        else:
            n_max = len(n_array)
            x_cut = np.sqrt(n_max + 1) * self._cut_scale
            if isinstance(x, int) or isinstance(x, float):
                if x >= x_cut:
                    return 0
                else:
                    return hermite.hermval(x, n_array)
            else:
                out = np.zeros_like(x)
                out[x < x_cut] = hermite.hermval(x[x < x_cut], n_array, tensor=tensor)
                return out


Instruction:
Create a Python 3 function for
returning the Hermite polynomial of order n at position x.

Response:
def H_n(self, n, x):
        """
        constructs the Hermite polynomial of order n at position x (dimensionless)

        :param n: The n'the basis function.
        :type name: int.
        :param x: 1-dim position (dimensionless)
        :type state: float or numpy array.
        :returns:  array-- H_n(x).
        :raises: AttributeError, KeyError
        """
        if not self._interpolation:
            n_array = np.zeros(n+1)
            n_array[n] = 1
            return self.hermval(x, n_array, tensor=False)  # attention, this routine calculates every single hermite polynomial and multiplies it with zero (exept the right one)
        else:
            return np.interp(x, self.x_grid, self.H_interp[n])


Instruction:
Can you generate a brief explanation for the following Python 3 code
def pre_calc(self, x, y, beta, n_order, center_x, center_y):
        x_ = x - center_x
        y_ = y - center_y
        n = len(np.atleast_1d(x))
        H_x = np.empty((n_order+1, n))
        H_y = np.empty((n_order+1, n))
        if n_order > 170:
            raise ValueError('polynomial order to large', n_order)
        for n in range(0, n_order+1):

            prefactor = 1./np.sqrt(2**n*np.sqrt(np.pi)*math.factorial(n))
            n_array = np.zeros(n+1)
            n_array[n] = 1
            H_x[n] = self.hermval(x_/beta, n_array, tensor=False) * prefactor * np.exp(-(x_/beta)**2/2.)
            H_y[n] = self.hermval(y_/beta, n_array, tensor=False) * prefactor * np.exp(-(y_/beta)**2/2.)
        return H_x, H_y

Response: Calculates the H_n x and H_n y for a given x - array and y - array.


Instruction:
Create a Python 3 function to
decompose an image into the shapelet coefficients in same order as for the function call :param image: :param x: :param y: :param n_max: :param beta: :param center_x: :param center_y: :return:

Response:
def decomposition(self, image, x, y, n_max, beta, deltaPix, center_x=0, center_y=0):
        """
        decomposes an image into the shapelet coefficients in same order as for the function call
        :param image:
        :param x:
        :param y:
        :param n_max:
        :param beta:
        :param center_x:
        :param center_y:
        :return:
        """
        num_param = int((n_max+1)*(n_max+2)/2)
        param_list = np.zeros(num_param)
        amp_norm = 1./beta**2*deltaPix**2
        n1 = 0
        n2 = 0
        H_x, H_y = self.shapelets.pre_calc(x, y, beta, n_max, center_x, center_y)
        for i in range(num_param):
            kwargs_source_shapelet = {'center_x': center_x, 'center_y': center_y, 'n1': n1, 'n2': n2, 'beta': beta, 'amp': amp_norm}
            base = self.shapelets.function(H_x, H_y, **kwargs_source_shapelet)
            param = np.sum(image*base)
            param_list[i] = param
            if n1 == 0:
                n1 = n2 + 1
                n2 = 0
            else:
                n1 -= 1
                n2 += 1
        return param_list


Instruction:
Here you have a function in Python 3, explain what it does
def _sample(self, maxIter=1000, c1=1.193, c2=1.193, lookback = 0.25, standard_dev = None):
        self._get_fitness(self.swarm)
        i = 0
        self.i = i
        while True:

            for particle in self.swarm:
                if ((self._gbest.fitness)<particle.fitness):

                    self._gbest = particle.copy()

                if (particle.fitness > particle.pbest.fitness):
                    particle.updatePBest()

            if(i>=maxIter):
                if self._verbose:
                    print("max iteration reached! stoping")
                return

            if self._func.is_converged:
                return

            if self._converged_likelihood(maxIter*lookback, self._particleCount, standard_dev):
                return

            for particle in self.swarm:

                w = 0.5 + numpy.random.uniform(0, 1, size=self._paramCount) / 2
                #w=0.72
                part_vel = w * particle.velocity
                cog_vel = c1 * numpy.random.uniform(0, 1, size=self._paramCount) * (particle.pbest.position - particle.position)
                soc_vel = c2 * numpy.random.uniform(0, 1, size=self._paramCount) * (self._gbest.position - particle.position)
                particle.velocity = part_vel + cog_vel + soc_vel
                particle.position = particle.position + particle.velocity

            self._get_fitness(self.swarm)

            swarm = []
            for particle in self.swarm:
                swarm.append(particle.copy())
            yield swarm

            i+=1
            self.i = i

Response: Generate a random set of random particles for a particular set of attributes.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def create(cls, paramCount):

        return Particle(numpy.array([[]]*paramCount),
                 numpy.array([[]]*paramCount),
                 -numpy.Inf)

Response: Creates a new particle with position velocity and - inf as fitness


Instruction:
Can you write a function in Python 3 where it
creates a copy of itself

Response:
def copy(self):
        """
        Creates a copy of itself
        """
        return Particle(copy(self.position),
                        copy(self.velocity),
                        self.fitness)


Instruction:
How would you implement a function in Python 3 that
resets all the cache in the point source class and saves it from then on

Response:
def reset_point_source_cache(self, bool=True):
        """
        deletes all the cache in the point source class and saves it from then on

        :return:
        """
        for imageModel in self._imageModel_list:
            imageModel.reset_point_source_cache(bool=bool)


Instruction:
Implement a Python 3 function for
computing quadrupole moments from a light distribution I_xy

Response:
def moments(I_xy_input, x, y):
    """
    compute quadrupole moments from a light distribution

    :param I_xy: light distribution
    :param x: x-coordinates of I_xy
    :param y: y-coordinates of I_xy
    :return: Q_xx, Q_xy, Q_yy
    """
    I_xy = copy.deepcopy(I_xy_input)
    background = np.minimum(0, np.min(I_xy))
    I_xy -= background
    x_ = np.sum(I_xy * x)
    y_ = np.sum(I_xy * y)
    r = (np.max(x) - np.min(x)) / 3.
    mask = mask_util.mask_sphere(x, y, center_x=x_, center_y=y_, r=r)
    Q_xx = np.sum(I_xy * mask * (x - x_) ** 2)
    Q_xy = np.sum(I_xy * mask * (x - x_) * (y - y_))
    Q_yy = np.sum(I_xy * mask * (y - y_) ** 2)
    return Q_xx, Q_xy, Q_yy, background / np.mean(I_xy)


Instruction:
How would you explain what the following Python 3 function does
def ellipticities(I_xy, x, y):
    Q_xx, Q_xy, Q_yy, bkg = moments(I_xy, x, y)
    norm = Q_xx + Q_yy + 2 * np.sqrt(Q_xx*Q_yy - Q_xy**2)
    e1 = (Q_xx - Q_yy) / norm
    e2 = 2 * Q_xy / norm
    return e1 / (1+bkg), e2 / (1+bkg)

Response: compute ellipticities of a light distribution


Instruction:
Can you tell what is the following Python 3 function doing
def ray_shooting(self, theta_x, theta_y, kwargs_lens, k=None):
        x = np.zeros_like(theta_x)
        y = np.zeros_like(theta_y)
        alpha_x = theta_x
        alpha_y = theta_y
        i = -1
        for i, idex in enumerate(self._sorted_redshift_index):
            delta_T = self._T_ij_list[i]
            x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)
            alpha_x, alpha_y = self._add_deflection(x, y, alpha_x, alpha_y, kwargs_lens, i)
        delta_T = self._T_ij_list[i+1]
        x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)
        beta_x, beta_y = self._co_moving2angle_source(x, y)
        return beta_x, beta_y

Response: ray shooting for the image


Instruction:
Create a Python 3 function to
ray shooting for a set of objects

Response:
def ray_shooting_partial(self, x, y, alpha_x, alpha_y, z_start, z_stop, kwargs_lens, keep_range=False,
                             include_z_start=False):
        """
        ray-tracing through parts of the coin, starting with (x,y) and angles (alpha_x, alpha_y) at redshift z_start
        and then backwards to redshfit z_stop

        :param x: co-moving position [Mpc]
        :param y: co-moving position [Mpc]
        :param alpha_x: ray angle at z_start [arcsec]
        :param alpha_y: ray angle at z_start [arcsec]
        :param z_start: redshift of start of computation
        :param z_stop: redshift where output is computed
        :param kwargs_lens: lens model keyword argument list
        :param keep_range: bool, if True, only computes the angular diameter ratio between the first and last step once
        :return: co-moving position and angles at redshift z_stop
        """
        z_lens_last = z_start
        first_deflector = True
        for i, idex in enumerate(self._sorted_redshift_index):
            z_lens = self._redshift_list[idex]
            if self._start_condition(include_z_start, z_lens, z_start) and z_lens <= z_stop:
            #if z_lens > z_start and z_lens <= z_stop:
                if first_deflector is True:
                    if keep_range is True:
                        if not hasattr(self, '_cosmo_bkg_T_start'):
                            self._cosmo_bkg_T_start = self._cosmo_bkg.T_xy(z_start, z_lens)
                        delta_T = self._cosmo_bkg_T_start
                    else:
                        delta_T = self._cosmo_bkg.T_xy(z_start, z_lens)
                    first_deflector = False
                else:
                    delta_T = self._T_ij_list[i]
                x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)
                alpha_x, alpha_y = self._add_deflection(x, y, alpha_x, alpha_y, kwargs_lens, i)
                z_lens_last = z_lens
        if keep_range is True:
            if not hasattr(self, '_cosmo_bkg_T_stop'):
                self._cosmo_bkg_T_stop = self._cosmo_bkg.T_xy(z_lens_last, z_stop)
            delta_T = self._cosmo_bkg_T_stop
        else:
            delta_T = self._cosmo_bkg.T_xy(z_lens_last, z_stop)
        x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)
        return x, y, alpha_x, alpha_y


Instruction:
Make a summary of the following Python 3 code
def ray_shooting_partial_steps(self, x, y, alpha_x, alpha_y, z_start, z_stop, kwargs_lens,
                             include_z_start=False):
        """
        ray-tracing through parts of the coin, starting with (x,y) and angles (alpha_x, alpha_y) at redshift z_start
        and then backwards to redshfit z_stop.

        This function differs from 'ray_shooting_partial' in that it returns the angular position of the ray
        at each lens plane.

        :param x: co-moving position [Mpc]
        :param y: co-moving position [Mpc]
        :param alpha_x: ray angle at z_start [arcsec]
        :param alpha_y: ray angle at z_start [arcsec]
        :param z_start: redshift of start of computation
        :param z_stop: redshift where output is computed
        :param kwargs_lens: lens model keyword argument list
        :param keep_range: bool, if True, only computes the angular diameter ratio between the first and last step once
        :return: co-moving position and angles at redshift z_stop
        """
        z_lens_last = z_start
        first_deflector = True

        pos_x, pos_y, redshifts, Tz_list = [], [], [], []
        pos_x.append(x)
        pos_y.append(y)
        redshifts.append(z_start)
        Tz_list.append(self._cosmo_bkg.T_xy(0, z_start))

        current_z = z_lens_last

        for i, idex in enumerate(self._sorted_redshift_index):

            z_lens = self._redshift_list[idex]

            if self._start_condition(include_z_start,z_lens,z_start) and z_lens <= z_stop:

                if z_lens != current_z:
                    new_plane = True
                    current_z = z_lens

                else:
                    new_plane = False

                if first_deflector is True:
                    delta_T = self._cosmo_bkg.T_xy(z_start, z_lens)

                    first_deflector = False
                else:
                    delta_T = self._T_ij_list[i]
                x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)
                alpha_x, alpha_y = self._add_deflection(x, y, alpha_x, alpha_y, kwargs_lens, i)
                z_lens_last = z_lens

                if new_plane:

                    pos_x.append(x)
                    pos_y.append(y)
                    redshifts.append(z_lens)
                    Tz_list.append(self._T_z_list[i])

        delta_T = self._cosmo_bkg.T_xy(z_lens_last, z_stop)

        x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)

        pos_x.append(x)
        pos_y.append(y)
        redshifts.append(self._z_source)
        Tz_list.append(self._T_z_source)

        return pos_x, pos_y, redshifts, Tz_list

Response: This function is used to perform ray shooting on a set of regions.


Instruction:
Can you tell what is the following Python 3 function doing
def arrival_time(self, theta_x, theta_y, kwargs_lens, k=None):
        dt_grav = np.zeros_like(theta_x)
        dt_geo = np.zeros_like(theta_x)
        x = np.zeros_like(theta_x)
        y = np.zeros_like(theta_y)
        alpha_x = theta_x
        alpha_y = theta_y
        i = 0
        for i, idex in enumerate(self._sorted_redshift_index):
            z_lens = self._redshift_list[idex]
            delta_T = self._T_ij_list[i]
            dt_geo_new = self._geometrical_delay(alpha_x, alpha_y, delta_T)
            x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)
            dt_grav_new = self._gravitational_delay(x, y, kwargs_lens, i, z_lens)
            alpha_x, alpha_y = self._add_deflection(x, y, alpha_x, alpha_y, kwargs_lens, i)
            dt_geo = dt_geo + dt_geo_new
            dt_grav = dt_grav + dt_grav_new
        delta_T = self._T_ij_list[i + 1]
        dt_geo += self._geometrical_delay(alpha_x, alpha_y, delta_T)
        x, y = self._ray_step(x, y, alpha_x, alpha_y, delta_T)
        beta_x, beta_y = self._co_moving2angle_source(x, y)
        dt_geo -= self._geometrical_delay(beta_x, beta_y, self._T_z_source)
        return dt_grav + dt_geo

Response: calculate light travel time relative to a straight path through the coordinate


Instruction:
Can you generate the documentation for the following Python 3 function
def alpha(self, theta_x, theta_y, kwargs_lens, k=None):
        beta_x, beta_y = self.ray_shooting(theta_x, theta_y, kwargs_lens)
        alpha_x = theta_x - beta_x
        alpha_y = theta_y - beta_y
        return alpha_x, alpha_y

Response:
reduced deflection angle

        :param theta_x: angle in x-direction
        :param theta_y: angle in y-direction
        :param kwargs_lens: lens model kwargs
        :return:


Instruction:
Create a Python 3 function to
compute the hessian components f_xx f_yy f_yx f_yy from f_x and f_y with numerical differentiation

Response:
def hessian(self, theta_x, theta_y, kwargs_lens, k=None, diff=0.00000001):
        """
        computes the hessian components f_xx, f_yy, f_xy from f_x and f_y with numerical differentiation

        :param theta_x: x-position (preferentially arcsec)
        :type theta_x: numpy array
        :param theta_y: y-position (preferentially arcsec)
        :type theta_y: numpy array
        :param kwargs_lens: list of keyword arguments of lens model parameters matching the lens model classes
        :param diff: numerical differential step (float)
        :return: f_xx, f_xy, f_yx, f_yy
        """

        alpha_ra, alpha_dec = self.alpha(theta_x, theta_y, kwargs_lens)

        alpha_ra_dx, alpha_dec_dx = self.alpha(theta_x + diff, theta_y, kwargs_lens)
        alpha_ra_dy, alpha_dec_dy = self.alpha(theta_x, theta_y + diff, kwargs_lens)

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

        f_xx = dalpha_rara
        f_yy = dalpha_decdec
        f_xy = dalpha_radec
        f_yx = dalpha_decra
        return f_xx, f_xy, f_yx, f_yy


Instruction:
Given the following Python 3 function, write the documentation
def _reduced2physical_deflection(self, alpha_reduced, idex_lens):
        factor = self._reduced2physical_factor[idex_lens]
        #factor = self._cosmo_bkg.D_xy(0, z_source) / self._cosmo_bkg.D_xy(z_lens, z_source)
        return alpha_reduced * factor

Response: Convert reduced deflection angle to physical deflection angle


Instruction:
Here you have a function in Python 3, explain what it does
def _geometrical_delay(self, alpha_x, alpha_y, delta_T):
        dt_days = (alpha_x**2 + alpha_y**2) / 2. * delta_T * const.Mpc / const.c / const.day_s * const.arcsec**2
        return dt_days

Response:
Compute the geometrical delay of a light ray with an angle relative to the shortest path
        and a transversal diameter distance between the start and end of the ray with an angle relative to the shortest path
       .


Instruction:
Explain what the following Python 3 code does
def _lensing_potential2time_delay(self, potential, z_lens, z_source):
        D_dt = self._cosmo_bkg.D_dt(z_lens, z_source)
        delay_days = const.delay_arcsec2days(potential, D_dt)
        return delay_days

Response: transforms the lensing potential to a gravitational time - delay as measured at z = 0


Instruction:
How would you explain what the following Python 3 function does
def _co_moving2angle(self, x, y, idex):
        T_z = self._T_z_list[idex]
        #T_z = self._cosmo_bkg.T_xy(0, z_lens)
        theta_x = x / T_z
        theta_y = y / T_z
        return theta_x, theta_y

Response: transforms co - moving distances Mpc into angles on the sky


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _co_moving2angle_source(self, x, y):
        T_z = self._T_z_source
        theta_x = x / T_z
        theta_y = y / T_z
        return theta_x, theta_y

Response: special case of the co_moving2angle definition at the source redshift


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _ray_step(self, x, y, alpha_x, alpha_y, delta_T):
        x_ = x + alpha_x * delta_T
        y_ = y + alpha_y * delta_T
        return x_, y_

Response: ray propagation with small angle approximation


Instruction:
Explain what the following Python 3 code does
def _add_deflection(self, x, y, alpha_x, alpha_y, kwargs_lens, idex):
        theta_x, theta_y = self._co_moving2angle(x, y, idex)
        alpha_x_red, alpha_y_red = self._lens_model.alpha(theta_x, theta_y, kwargs_lens, k=self._sorted_redshift_index[idex])
        alpha_x_phys = self._reduced2physical_deflection(alpha_x_red, idex)
        alpha_y_phys = self._reduced2physical_deflection(alpha_y_red, idex)
        alpha_x_new = alpha_x - alpha_x_phys
        alpha_y_new = alpha_y - alpha_y_phys
        return alpha_x_new, alpha_y_new

Response: Adds the pyhsical deflection angle to the deflection field of a single lens model


Instruction:
Here you have a function in Python 3, explain what it does
def derivatives(self, x, y, theta_E, center_x=0, center_y=0):
        x_shift = x - center_x
        y_shift = y - center_y
        R = np.sqrt(x_shift*x_shift + y_shift*y_shift)
        if isinstance(R, int) or isinstance(R, float):
            a = theta_E / max(0.000001, R)
        else:
            a=np.empty_like(R)
            r = R[R > 0]  #in the SIS regime
            a[R == 0] = 0
            a[R > 0] = theta_E / r
        f_x = a * x_shift
        f_y = a * y_shift
        return f_x, f_y

Response: returns df x y of the function


Instruction:
How would you explain what the following Python 3 function does
def hessian(self, x, y, theta_E, center_x=0, center_y=0):
        x_shift = x - center_x
        y_shift = y - center_y
        R = (x_shift*x_shift + y_shift*y_shift)**(3./2)
        if isinstance(R, int) or isinstance(R, float):
            prefac = theta_E / max(0.000001, R)
        else:
            prefac = np.empty_like(R)
            r = R[R>0]  #in the SIS regime
            prefac[R==0] = 0.
            prefac[R>0] = theta_E / r

        f_xx = y_shift*y_shift * prefac
        f_yy = x_shift*x_shift * prefac
        f_xy = -x_shift*y_shift * prefac
        return f_xx, f_yy, f_xy

Response: returns Hessian matrix of function d^2f x y theta_E


Instruction:
Can you create a Python 3 function that
functions that computes the profile of a single node.

Response:
def function(x, y, amp, a_x, a_y, center_x, center_y):
    """
    returns torus (ellipse with constant surface brightnes) profile
    """
    x_shift = x - center_x
    y_shift = y - center_y
    A = np.pi * a_x * a_y
    dist = (x_shift/a_x)**2 + (y_shift/a_y)**2
    torus = np.zeros_like(x)
    torus[dist <= 1] = 1
    return amp/A * torus


Instruction:
How would you implement a function in Python 3 that
functions to compute the source plane positions corresponding to the image

Response:
def ray_shooting(self, x, y, kwargs, k=None):
        """
        maps image to source position (inverse deflection)
        :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: source plane positions corresponding to (x, y) in the image plane
        """
        dx, dy = self.alpha(x, y, kwargs, k=k)
        return x - dx, y - dy


Instruction:
Write a Python 3 function that can
return the fermat potential of the image at the given coordinates

Response:
def fermat_potential(self, x_image, y_image, x_source, y_source, kwargs_lens, k=None):
        """
        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
        """

        potential = self.potential(x_image, y_image, kwargs_lens, k=k)
        geometry = ((x_image - x_source)**2 + (y_image - y_source)**2) / 2.
        return geometry - potential


Instruction:
How would you implement a function in Python 3 that
lenses potential for a given set of points x y and kwargs

Response:
def potential(self, x, y, kwargs, k=None):
        """
        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
        """
        x = np.array(x, dtype=float)
        y = np.array(y, dtype=float)
        bool_list = self._bool_list(k)
        x_, y_, kwargs_copy = self._update_foreground(x, y, kwargs)
        potential = np.zeros_like(x)
        for i, func in enumerate(self.func_list):
            if bool_list[i] is True:
                if self._model_list[i] == 'SHEAR':
                    potential += func.function(x, y, **kwargs[i])
                else:
                    potential += func.function(x_, y_, **kwargs_copy[i])
        return potential


Instruction:
Can you generate a brief explanation for the following Python 3 code
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
        """
        x = np.array(x, dtype=float)
        y = np.array(y, dtype=float)
        bool_list = self._bool_list(k)
        x_, y_, kwargs_copy = self._update_foreground(x, y, kwargs)
        f_x, f_y = np.zeros_like(x_), np.zeros_like(x_)
        for i, func in enumerate(self.func_list):
            if bool_list[i] is True:
                if self._model_list[i] == 'SHEAR':
                    f_x_i, f_y_i = func.derivatives(x, y, **kwargs[i])
                else:
                    f_x_i, f_y_i = func.derivatives(x_, y_, **kwargs_copy[i])
                f_x += f_x_i
                f_y += f_y_i
        return f_x, f_y

Response: compute the deflection angles for the current lens model class


Instruction:
Write a Python 3 script to
compute the hessian of the lens model class

Response:
def hessian(self, x, y, kwargs, k=None):
        """
        hessian matrix
        :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: f_xx, f_xy, f_yy components
        """
        x = np.array(x, dtype=float)
        y = np.array(y, dtype=float)
        if self._foreground_shear:
            # needs to be computed numerically due to non-linear effects
            f_xx, f_xy, f_yx, f_yy = self.hessian_differential(x, y, kwargs, k=k)
        else:
            bool_list = self._bool_list(k)
            x_ = x
            y_ = y
            f_xx, f_yy, f_xy = np.zeros_like(x_), np.zeros_like(x_), np.zeros_like(x_)
            for i, func in enumerate(self.func_list):
                if bool_list[i] is True:
                    f_xx_i, f_yy_i, f_xy_i = func.hessian(x_, y_, **kwargs[i])
                    f_xx += f_xx_i
                    f_yy += f_yy_i
                    f_xy += f_xy_i
        f_yx = f_xy
        return f_xx, f_xy, f_yx, f_yy


Instruction:
Write a Python 3 script to
compute the mass of a 3d sphere of radius r

Response:
def mass_3d(self, r, kwargs, bool_list=None):
        """
        computes the mass within a 3d sphere of radius r

        :param r: radius (in angular units)
        :param kwargs: list of keyword arguments of lens model parameters matching the lens model classes
        :param bool_list: list of bools that are part of the output
        :return: mass (in angular units, modulo epsilon_crit)
        """
        bool_list = self._bool_list(bool_list)
        mass_3d = 0
        for i, func in enumerate(self.func_list):
            if bool_list[i] is True:
                kwargs_i = {k:v for k, v in kwargs[i].items() if not k in ['center_x', 'center_y']}
                mass_3d_i = func.mass_3d_lens(r, **kwargs_i)
                mass_3d += mass_3d_i
                #except:
                #    raise ValueError('Lens profile %s does not support a 3d mass function!' % self.model_list[i])
        return mass_3d


Instruction:
Make a summary of the following Python 3 code
def mass_2d(self, r, kwargs, bool_list=None):
        bool_list = self._bool_list(bool_list)
        mass_2d = 0
        for i, func in enumerate(self.func_list):
            if bool_list[i] is True:
                kwargs_i = {k: v for k, v in kwargs[i].items() if not k in ['center_x', 'center_y']}
                mass_2d_i = func.mass_2d_lens(r, **kwargs_i)
                mass_2d += mass_2d_i
                #except:
                #    raise ValueError('Lens profile %s does not support a 2d mass function!' % self.model_list[i])
        return mass_2d

Response: computes the projected mass of a 2d radius r


Instruction:
Make a summary of the following Python 3 code
def _bool_list(self, k=None):
        n = len(self.func_list)
        if k is None:
            bool_list = [True] * n
        elif isinstance(k, (int, np.integer)):
            bool_list = [False] * n
            bool_list[k] = True
        else:
            bool_list = [False] * n
            for i, k_i in enumerate(k):
                if k_i is not False:
                    if k_i is True:
                        bool_list[i] = True
                    elif k_i < n:
                        bool_list[k_i] = True
                    else:
                        raise ValueError("k as set by %s is not convertable in a bool string!" % k)
        if self._foreground_shear is True:
            bool_list[self._foreground_shear_idex] = False
        return bool_list

Response: returns a list of the length of the lens models


Instruction:
Write a Python 3 script for
generating a open namespace from symbol namespace x y z

Response:
def open_ns(symbol):
        ''' generates a open namespace from symbol namespace x { y { z {'''
        blocks = ['namespace {0} {{'.format(x) for x in symbol.module.name_parts]
        return ' '.join(blocks)


Instruction:
Can you create a Python 3 function that
generates a closing names statement from a symbol

Response:
def close_ns(symbol):
        '''generates a closing names statement from a symbol'''
        closing = ' '.join(['}' for x in symbol.module.name_parts])
        name = '::'.join(symbol.module.name_parts)
        return '{0} // namespace {1}'.format(closing, name)


Instruction:
Here you have a function in Python 3, explain what it does
def ns(symbol):
        '''generates a namespace x::y::z statement from a symbol'''
        if symbol.type and symbol.type.is_primitive:
            return ''
        return '{0}::'.format('::'.join(symbol.module.name_parts))

Response: generates a namespace x :: y :: z statement from a symbol


Instruction:
Write a Python 3 script for
taking several files or directories as src and generates the code in the given dst directory.

Response:
def app(config, src, dst, features, reload, force):
    """Takes several files or directories as src and generates the code
    in the given dst directory."""
    config = Path(config)
    if reload:
        argv = sys.argv.copy()
        argv.remove('--reload')
        monitor(config.dirname(), src, dst, argv)
    else:
        run(config, src, dst, force)


Instruction:
Given the following Python 3 function, write the documentation
def reload(script, input, output):
    script = Path(script).expand().abspath()
    output = Path(output).expand().abspath()
    input = input if isinstance(input, (list, tuple)) else [input]
    output.makedirs_p()
    _script_reload(script, input, output)

Response:
Reloads the generator script when the script files
    or the input files changes


Instruction:
Can you generate a brief explanation for the following Python 3 code
def _script_reload(script, input, output):
    input = [Path(entry).expand().abspath() for entry in input]
    output = Path(output).expand().abspath()
    cmd = 'python3 {0} {1} {2}'.format(script, ' '.join(input), output)
    event_handler = RunScriptChangeHandler(cmd)
    event_handler.run()  # run always once
    observer = Observer()
    path = script.dirname().expand().abspath()
    click.secho('watch: {0}'.format(path), fg='blue')
    observer.schedule(event_handler, path, recursive=True)
    for entry in input:
        entry = entry.dirname().expand().abspath()
        click.secho('watch: {0}'.format(entry), fg='blue')
        observer.schedule(event_handler, entry, recursive=True)
    path = Path(__file__).parent / 'qface'
    click.secho('watch: {0}'.format(path), fg='blue')
    observer.schedule(event_handler, path, recursive=True)
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

Response: run the named generator and monitor the input and generator folder


Instruction:
Write a Python 3 function for
installing the script onto the system using pip3

Response:
def install(editable):
    """install the script onto the system using pip3"""
    script_dir = str(Path(__file__).parent.abspath())
    click.secho(script_dir, fg='blue')
    if editable:
        sh('pip3 install --editable {0} --upgrade'.format(script_dir))
    else:
        sh('pip3 install {0} --upgrade'.format(script_dir))


Instruction:
Make a summary of the following Python 3 code
def merge(a, b):
    "merges b into a recursively if a and b are dicts"
    for key in b:
        if isinstance(a.get(key), dict) and isinstance(b.get(key), dict):
            merge(a[key], b[key])
        else:
            a[key] = b[key]
    return a

Response: merges b into a recursively if a and b are dicts


Instruction:
Can you write a function in Python 3 where it
retrieves a single template file from the template loader

Response:
def get_template(self, name):
        """Retrieves a single template file from the template loader"""
        source = name
        if name and name[0] is '/':
            source = name[1:]
        elif self.source is not None:
            source = '/'.join((self.source, name))
        return self.env.get_template(source)


Instruction:
Can you tell what is the following Python 3 function doing
def render(self, name, context):
        if Generator.strict:
            self.env.undefined = TestableUndefined
        else:
            self.env.undefined = Undefined
        template = self.get_template(name)
        return template.render(context)

Response: Returns the rendered text from a single template file from the base class


Instruction:
Write a Python 3 script to
return the rendered text of a template instance

Response:
def apply(self, template, context={}):
        context.update(self.context)
        """Return the rendered text of a template instance"""
        return self.env.from_string(template).render(context)


Instruction:
Write a Python 3 script for
writing a template into a file given a context.

Response:
def write(self, file_path, template, context={}, preserve=False, force=False):
        """Using a template file name it renders a template
           into a file given a context
        """
        if not file_path or not template:
            click.secho('source or target missing for document')
            return
        if not context:
            context = self.context
        error = False
        try:
            self._write(file_path, template, context, preserve, force)
        except TemplateSyntaxError as exc:
            message = '{0}:{1}: error: {2}'.format(exc.filename, exc.lineno, exc.message)
            click.secho(message, fg='red', err=True)
            error = True
        except TemplateNotFound as exc:
            message = '{0}: error: Template not found'.format(exc.name)
            click.secho(message, fg='red', err=True)
            error = True
        except TemplateError as exc:
            # Just return with an error, the generic template_error_handler takes care of printing it
            error = True

        if error and Generator.strict:
            sys.exit(1)


Instruction:
Write a Python 3 script for
reading the templates read from the rules document

Response:
def process_rules(self, path: Path, system: System):
        """writes the templates read from the rules document"""
        self.context.update({
            'system': system,
        })
        document = FileSystem.load_yaml(path, required=True)
        for module, rules in document.items():
            click.secho('process: {0}'.format(module), fg='green')
            self._process_rules(rules, system)


Instruction:
Write a Python 3 script for
processing a set of rules for a target

Response:
def _process_rules(self, rules: dict, system: System):
        """ process a set of rules for a target """
        self._source = None # reset the template source
        if not self._shall_proceed(rules):
            return
        self.context.update(rules.get('context', {}))
        self.path = rules.get('path', '')
        self.source = rules.get('source', None)
        self._process_rule(rules.get('system', None), {'system': system})
        for module in system.modules:
            self._process_rule(rules.get('module', None), {'module': module})
            for interface in module.interfaces:
                self._process_rule(rules.get('interface', None), {'interface': interface})
            for struct in module.structs:
                self._process_rule(rules.get('struct', None), {'struct': struct})
            for enum in module.enums:
                self._process_rule(rules.get('enum', None), {'enum': enum})


Instruction:
Here you have a function in Python 3, explain what it does
def _process_rule(self, rule: dict, context: dict):
        if not rule or not self._shall_proceed(rule):
            return
        self.context.update(context)
        self.context.update(rule.get('context', {}))
        self.path = rule.get('path', None)
        self.source = rule.get('source', None)
        for entry in rule.get('documents', []):
            target, source = self._resolve_rule_document(entry)
            self.write(target, source)
        for entry in rule.get('preserve', []):
            target, source = self._resolve_rule_document(entry)
            self.write(target, source, preserve=True)

Response: process a single rule


Instruction:
Create a Python 3 function for
parsing a document and returns the resulting domain

Response:
def _parse_document(document: Path, system: System = None, profile=EProfile.FULL):
        """Parses a document and returns the resulting domain system

        :param path: document path to parse
        :param system: system to be used (optional)
        """
        logger.debug('parse document: {0}'.format(document))
        stream = FileStream(str(document), encoding='utf-8')
        system = FileSystem._parse_stream(stream, system, document, profile)
        FileSystem.merge_annotations(system, document.stripext() + '.yaml')
        return system


Instruction:
Can you implement a function in Python 3 that
reads a YAML document and for each root symbol identifier updates the tag information of that root symbol identifier

Response:
def merge_annotations(system, document):
        """Read a YAML document and for each root symbol identifier
        updates the tag information of that symbol
        """
        if not Path(document).exists():
            return
        meta = FileSystem.load_yaml(document)
        click.secho('merge: {0}'.format(document.name), fg='blue')
        for identifier, data in meta.items():
            symbol = system.lookup(identifier)
            if symbol:
                merge(symbol.tags, data)


Instruction:
Here you have a function in Python 3, explain what it does
def parse(input, identifier: str = None, use_cache=False, clear_cache=True, pattern="*.qface", profile=EProfile.FULL):
        inputs = input if isinstance(input, (list, tuple)) else [input]
        logger.debug('parse input={0}'.format(inputs))
        identifier = 'system' if not identifier else identifier
        system = System()
        cache = None
        if use_cache:
            cache = shelve.open('qface.cache')
            if identifier in cache and clear_cache:
                del cache[identifier]
            if identifier in cache:
                # use the cached domain model
                system = cache[identifier]
        # if domain model not cached generate it
        for input in inputs:
            path = Path.getcwd() / str(input)
            if path.isfile():
                FileSystem.parse_document(path, system)
            else:
                for document in path.walkfiles(pattern):
                    FileSystem.parse_document(document, system)

        if use_cache:
            cache[identifier] = system
        return system

Response: Parse a directory or a list of files or directories and return a System object.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def monitor(args, watch):
    watch = watch if isinstance(watch, (list, tuple)) else [watch]
    watch = [Path(entry).expand().abspath() for entry in watch]
    event_handler = RunScriptChangeHandler(args)
    observer = Observer()
    for entry in watch:
        if entry.isfile():
            entry = entry.parent
        click.secho('watch recursive: {0}'.format(entry), fg='blue')
        observer.schedule(event_handler, entry, recursive=True)
    event_handler.run()  # run always once
    observer.start()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

Response: watch the src files of the current node


Instruction:
Can you generate a brief explanation for the following Python 3 code
def qualified_name(self):
        '''return the fully qualified name (`<module>.<name>`)'''
        if self.module == self:
            return self.module.name
        else:
            if "." not in self.name:
                return '{0}.{1}'.format(self.module.name, self.name)
            else:
                # We have a fully qualified reference, just return it
                return self.name

Response: return the fully qualified name


Instruction:
Make a summary of the following Python 3 code
def add_tag(self, tag):
        if tag not in self._tags:
            self._tags[tag] = dict()

Response: add a tag to the tag list


Instruction:
Write a Python 3 script to
add an attribute to the named tag

Response:
def add_attribute(self, tag, name, value):
        """ add an attribute (nam, value pair) to the named tag """
        self.add_tag(tag)
        d = self._tags[tag]
        d[name] = value


Instruction:
Write a Python 3 script to
return attribute by tag and attribute name

Response:
def attribute(self, tag, name):
        """ return attribute by tag and attribute name """
        if tag in self._tags and name in self._tags[tag]:
            return self._tags[tag][name]


Instruction:
Write a Python 3 script to
check if type is a valid type

Response:
def is_valid(self):
        '''checks if type is a valid type'''
        return (self.is_primitive and self.name) \
            or (self.is_complex and self.name) \
            or (self.is_list and self.nested) \
            or (self.is_map and self.nested) \
            or (self.is_model and self.nested)


Instruction:
Can you generate the documentation for the following Python 3 function
def _resolve(self):
        self.__is_resolved = True
        if self.is_complex:
            type = self.nested if self.nested else self
            type.__reference = self.module.lookup(type.name)

Response: resolve the type symbol from name by doing a lookup


Instruction:
Can you generate a brief explanation for the following Python 3 code
def lookup(self, name: str, fragment: str = None):
        '''lookup a symbol by name. If symbol is not local
        it will be looked up system wide'''
        if name in self._contentMap:
            symbol = self._contentMap[name]
            if fragment:
                return symbol._contentMap[fragment]
            return symbol
        return self.system.lookup(name)

Response: lookup a symbol by name.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def qualified_name(self):
        '''return the fully qualified name (`<module>.<interface>#<operation>`)'''
        return '{0}.{1}#{2}'.format(self.module.name, self.interface.name, self.name)

Response: return the fully qualified name


Instruction:
Can you generate the documentation for the following Python 3 function
def qualified_name(self):
        '''return the fully qualified name (`<module>.<struct>#<field>`)'''
        return '{0}.{1}#{2}'.format(self.module.name, self.struct.name, self.name)

Response: return the fully qualified name


Instruction:
Write a Python 3 script for
returning the fully qualified name

Response:
def qualified_name(self):
        '''return the fully qualified name (`<module>.<enum>#<member>`)'''
        return '{0}.{1}#{2}'.format(self.module.name, self.enum.name, self.name)


Instruction:
Explain what the following Python 3 code does
def jsonify(symbol):
    try:
        # all symbols have a toJson method, try it
        return json.dumps(symbol.toJson(), indent='  ')
    except AttributeError:
        pass
    return json.dumps(symbol, indent='  ')

Response: returns json format for symbol


Instruction:
Can you generate the documentation for the following Python 3 function
def hash(symbol, hash_type='sha1'):
    code = hashlib.new(hash_type)
    code.update(str(symbol).encode('utf-8'))
    return code.hexdigest()

Response: create a hash code from symbol


Instruction:
Write a Python 3 function that can
run the given cmd as shell command

Response:
def sh(args, **kwargs):
    """
    runs the given cmd as shell command
    """
    if isinstance(args, str):
        args = args.split()
    if not args:
        return
    click.echo('$ {0}'.format(' '.join(args)))
    try:
        return subprocess.check_call(args, **kwargs)
    except subprocess.CalledProcessError as exc:
        click.secho('run error {}'.format(exc))
    except OSError as exc:
        click.secho('not found error {}'.format(exc))


Instruction:
Write a Python 3 script to
parse a JavaDoc string and returns an object where each JavaDoc tag is a property of the object.

Response:
def parse_doc(s):
    """ parse a comment in the format of JavaDoc and returns an object, where each JavaDoc tag
        is a property of the object. """
    if not s:
        return
    doc = DocObject()
    tag = None
    s = s[3:-2]  # remove '/**' and '*/'
    for line in s.splitlines():
        line = line.lstrip(' *')  # strip a ' ' and '*' from start
        if not line:
            tag = None  # on empty line reset the tag information
        elif line[0] == '@':
            line = line[1:]
            res = line.split(maxsplit=1)
            if len(res) == 0:
                continue
            tag = res[0]
            if len(res) == 1:
                doc.add_tag(tag, True)
            elif len(res) == 2:
                value = res[1]
                doc.add_tag(tag, value)
        elif tag:  # append to previous matched tag
            doc.add_tag(tag, line)
        else: # append any loose lines to description
            doc.add_tag('description', line)
    return doc


Instruction:
Make a summary of the following Python 3 code
def has_permission(self, request, view):
        url_username = request.parser_context.get('kwargs', {}).get('username', '')
        if request.user.username.lower() != url_username.lower():
            if request.user.is_staff:
                return False  # staff gets 403
            raise Http404()
        return True

Response: Returns true if the current request is by the user itself.


Instruction:
Can you generate the documentation for the following Python 3 function
def db_type(self, connection):
        conn_module = type(connection).__module__
        if "mysql" in conn_module:
            return "bigint AUTO_INCREMENT"
        elif "postgres" in conn_module:
            return "bigserial"
        return super(BigAutoField, self).db_type(connection)

Response: Returns the type of the field to insert into the database.