示例#1
0
def _fractionTotalFLuxEllipse(a: float, image: np.ndarray, b: float,
                              theta: float, centre: List[float],
                              totalsum: float) -> float:
    '''Function calculates the fraction of the total flux for the given
       elliptical parameters

       Parameters
       ----------

        a : float
            Semi-major axis or width. Must be positive

        image : np.ndarray
            image for which flux will be counted

        b : float
            Ellipses semi-minor axis or hight

        theta : float
            Rotation of ellipse w.r.t the positive x axis anticlockwise

        centre : List[float]
            centre of the ellipse.

        totalsum : float
            total flux of the object.

       Returns
       -------

       The fraction of the total flux of the object as defined by the input
       parameters minus 50% so that this function can be used to find a root at
       50% total flux : float

    '''

    apCur = EllipticalAperture(centre, a, b, theta)
    curSum = apCur.do_photometry(image, method="exact")[0][0]

    return (curSum / totalsum) - 0.5
示例#2
0
def fitSersic(image: np.ndarray,
              centroid: List[float],
              fwhms: List[float],
              theta: float,
              starMask=None):
    '''Function that fits a 2D sersic function to an image of a Galaxy.

    Parameters
    ----------

    image : np.ndarray
        image to which a 2D Sersic function will be fit
    centroid : List[float]
        Centre of object of interest
    fwhms : List[float]
        Full width half maximums of object
    theta : float
        rotation of object anticlockwise from positive x axis
    starMask : np.ndarray
        Mask contains star locations.

    Returns
    -------

    Parameters : astropy.modeling.Model object

        Collection of best fit parameters for the 2D sersic function

    '''

    if starMask is None:
        imageCopy = image
    else:
        imageCopy = image * starMask

    fit_p = fitting.LevMarLSQFitter()

    # amplitude => Surface brightness at r_eff
    # r_eff => Effective (half-light) radius
    # n => sersic index, guess 1.?

    b = 2. * min(fwhms)
    a = 2. * max(fwhms)
    ellip = 1. - (b / a)

    apertureTotal = EllipticalAperture(centroid, a, b, theta)
    totalSum = apertureTotal.do_photometry(imageCopy, method="exact")[0][0]

    # get bracketing values for root finder to find r_eff
    deltaA = (a / 100.) * 2.
    aCurrent = a - deltaA
    aMin = 0
    aMax = 0
    while True:
        apertureCurrent = EllipticalAperture(centroid, aCurrent, b, theta)
        currentSum = apertureCurrent.do_photometry(imageCopy,
                                                   method="exact")[0][0]
        currentFraction = currentSum / totalSum
        if currentFraction <= .5:
            aMin = aCurrent
            aMax = aCurrent + deltaA
            break
        aCurrent -= deltaA

    # get root
    r_eff = brentq(_fractionTotalFLuxEllipse,
                   aMin,
                   aMax,
                   args=(imageCopy, b, theta, centroid, totalSum))

    # calculate amplitude at r_eff
    a_in = r_eff - 0.5
    a_out = r_eff + 0.5
    b_out = a_out - (1. * ellip)
    ellip_annulus = EllipticalAnnulus(centroid, a_in, a_out, b_out, theta)
    totalR_effFlux = ellip_annulus.do_photometry(imageCopy,
                                                 method="exact")[0][0]
    meanR_effFlux = totalR_effFlux / ellip_annulus.area

    sersic_init = models.Sersic2D(amplitude=meanR_effFlux,
                                  r_eff=r_eff,
                                  n=2.0,
                                  x_0=centroid[0],
                                  y_0=centroid[1],
                                  ellip=ellip,
                                  theta=theta)

    ny, nx = imageCopy.shape
    y, x = np.mgrid[0:ny, 0:nx]

    Parameters = fit_p(sersic_init, x, y, imageCopy, maxiter=1000, acc=1e-8)

    return Parameters