def __init__(self, g_parameters, image_renderer, snr):
        self.g_parameters = g_parameters
        self.snr = snr
        self.model = galfun.getGalaxiesModels(g_parameters=self.g_parameters)
        self.image_renderer = image_renderer

        #we do not want to mask or crop the images used to obtain the partials. 
        self.image_renderer_partials = galfun.ImageRenderer(stamp=self.image_renderer.stamp)
        self.image = self.image_renderer.getImage(self.model)
        _, self.var_noise = galfun.addNoise(self.image, self.snr, 0)

        self.steps = defaults.getSteps(self.g_parameters, self.image_renderer)
        self.param_names = g_parameters.ordered_fit_names
        self.num_params = len(self.param_names)
        self.num_galaxies = self.g_parameters.num_galaxies

        self.derivatives_images = self.derivativesImages()
        self.second_derivatives_images = self.secondDerivativesImages()
        self.fisher_matrix_images = self.fisherMatrixImages()
        self.fisher_matrix = self.fisherMatrix()
        self.covariance_matrix = self.covarianceMatrix()
        self.correlation_matrix = self.correlationMatrix()
        self.bias_matrix_images = self.biasMatrixImages()
        self.bias_matrix = self.biasMatrix()
        self.bias_images = self.biasImages()
        self.biases = self.getBiases()

        self.fisher_condition_number = self.fisherConditionNumber()
    def derivativesImages(self):
        """Return images of the partial derivatives of the galaxy.

        The partial differentiation includes each of the different parameters
        that describe the galaxy.
        """
        partials_images = {}
        for i in range(self.num_params):
            param = self.param_names[i]
            params_up = copy.deepcopy(self.g_parameters.params)
            params_up[param] += self.steps[param]
            params_down = copy.deepcopy(self.g_parameters.params)
            params_down[param] -= self.steps[param]
            gal_up = galfun.getGalaxiesModels(params_up)
            gal_down = galfun.getGalaxiesModels(params_down)
            img_up = self.image_renderer_partials.getImage(gal_up)
            img_down = self.image_renderer_partials.getImage(gal_down)
            partials_images[param] =  ((img_up - img_down)/(2 * self.steps[param])).array
        return partials_images
    def secondDerivativesImages(self):
        """Return the images for the second derivatives of the given galaxy."""
        secondDs_gal = {}
        for i in range(self.num_params):
            for j in range(self.num_params):
                param_i = self.param_names[i]
                param_j = self.param_names[j]

                params_iup_jup = copy.deepcopy(self.g_parameters.params)
                params_iup_jup[param_i] += self.steps[param_i]
                params_iup_jup[param_j] += self.steps[param_j]

                params_idown_jup = copy.deepcopy(self.g_parameters.params)
                params_idown_jup[param_i] -= self.steps[param_i]
                params_idown_jup[param_j] += self.steps[param_j]   

                params_iup_jdown = copy.deepcopy(self.g_parameters.params)
                params_iup_jdown[param_i] += self.steps[param_i]
                params_iup_jdown[param_j] -= self.steps[param_j] 


                params_idown_jdown = copy.deepcopy(self.g_parameters.params)
                params_idown_jdown[param_i] -= self.steps[param_i]
                params_idown_jdown[param_j] -= self.steps[param_j]

                gal_iup_jup = galfun.getGalaxiesModels(params_iup_jup)
                gal_idown_jup = galfun.getGalaxiesModels(params_idown_jup)
                gal_iup_jdown = galfun.getGalaxiesModels(params_iup_jdown)
                gal_idown_jdown = galfun.getGalaxiesModels(params_idown_jdown)

                img_iup_jup = self.image_renderer_partials.getImage(gal_iup_jup)
                img_idown_jup = self.image_renderer_partials.getImage(gal_idown_jup)
                img_iup_jdown = self.image_renderer_partials.getImage(gal_iup_jdown)
                img_idown_jdown = self.image_renderer_partials.getImage(gal_idown_jdown)

                secondDs_gal[param_i, param_j] = ((img_iup_jup + img_idown_jdown - 
                                                   img_idown_jup - img_iup_jdown)/
                                                   (4*self.steps[param_i]*self.steps[param_j])).array

        return secondDs_gal
def objFunc(fit_params, image_renderer, data, variance_noise, **kwargs):
    gal_model = galfun.getGalaxiesModels(fit_params=fit_params.valuesdict(),**kwargs)
    model = image_renderer.getImage(gal_model)
    return ((model - data).array.ravel()) / math.sqrt(variance_noise)