Source code for lenstronomy.Util.multi_gauss_expansion

__author__ = "ajshajib", "sibirrer"
"""
Multi-Gaussian expansion fitting, based on Capellari 2002, http://adsabs.harvard.edu/abs/2002MNRAS.333..400C
"""

import numpy as np
from scipy.optimize import nnls
import warnings
from lenstronomy.Util.package_util import exporter
from lenstronomy.LightModel.Profiles.gaussian import Gaussian

gaussian_func = Gaussian()

export, __all__ = exporter()


[docs] @export def gaussian(R, sigma, amp): """ :param R: radius :param sigma: gaussian sigma :param amp: normalization :return: Gaussian function """ c = amp / (2 * np.pi * sigma**2) return c * np.exp(-((R / float(sigma)) ** 2) / 2.0)
[docs] @export def mge_1d(r_array, flux_r, N=20, linspace=False): """ :param r_array: list or radii (numpy array) :param flux_r: list of flux values (numpy array) :param N: number of Gaussians :return: amplitudes and Gaussian sigmas for the best 1d flux profile """ if N == 0: warnings.warn( "Number of MGE went down to zero! This should not happen!", Warning ) amplitudes = [0] sigmas = [1] norm = 0 return amplitudes, sigmas, norm try: amplitudes, sigmas, norm = _mge_1d(r_array, flux_r, N, linspace=linspace) except: N_new = N - 1 amplitudes, sigmas, norm = mge_1d(r_array, flux_r, N=N_new, linspace=linspace) return amplitudes, sigmas, norm
@export def _mge_1d(r_array, flux_r, N=20, linspace=False): """ :param r_array: :param flux_r: :param N: :return: """ if linspace is True: sigmas = np.linspace(r_array[0], r_array[-1] / 2, N + 2)[1:-1] else: sigmas = np.logspace( np.log10(r_array[0]), np.log10((r_array[-1] + 0.0000001) / 2.0), N + 2 )[1:-1] # sigmas = np.linspace(r_array[0], r_array[-1]/2, N + 2)[1:-1] A = np.zeros((len(flux_r), N)) for j in np.arange(A.shape[1]): A[:, j] = gaussian(r_array, sigmas[j], 1.0) amplitudes, norm = nnls(A, flux_r) return amplitudes, sigmas, norm
[docs] @export def de_projection_3d(amplitudes, sigmas): """De-projects a gaussian (or list of multiple Gaussians from a 2d projected to a 3d profile) :param amplitudes: :param sigmas: :return: """ amplitudes_3d = amplitudes / sigmas / np.sqrt(2 * np.pi) return amplitudes_3d, sigmas