예제 #1
0
def compareW(PSF,sig,accd,cx,cy):
    x1, y1 = centroid_com(PSF)
    x2, y2 = centroid_1dg(PSF)
    x3, y3 = centroid_2dg(PSF)
    errx1=cx-1-x1
    erry1=cy-1-y1
    errx2=cx-1-x2
    erry2=cy-1-y2
    errx3=cx-1-x3
    erry3=cy-1-y3
    err1=((errx1)**2+(erry1)**2)**0.5
    err2=((errx2)**2+(erry2)**2)**0.5
    err3=((errx3)**2+(erry3)**2)**0.5    
#    print("%.2e,%.2e,%.2e,%.2e,%.2e,%.2e," % ( errx1,erry1,errx2,erry2,errx3,erry3))

    # Weighted
    Weight=GaussianFunc(sig,accd,cx,cy)
    PSFW=PSF*Weight
    x1, y1 = centroid_com(PSFW)
    x2, y2 = centroid_1dg(PSFW)
    x3, y3 = centroid_2dg(PSFW)
    errx12=cx-1-x1
    erry12=cy-1-y1
    errx22=cx-1-x2
    erry22=cy-1-y2
    errx32=cx-1-x3
    erry32=cy-1-y3
    err12=((errx12)**2+(erry12)**2)**0.5
    err22=((errx22)**2+(erry22)**2)**0.5
    err32=((errx32)**2+(erry32)**2)**0.5    
#    print("%.2e,%.2e,%.2e,%.2e,%.2e,%.2e," % ( errx12,erry12,errx22,erry22,errx32,erry32))
    return  err1,err2,err3,err12,err22,err32
예제 #2
0
def Centroids(Stars, References, Trim=0, Plot=False):
    """
	Calculate the centroid offsets for a set of reference stars.
	"""
    flags = np.zeros((Stars.shape[0]))
    centroids = np.zeros((Stars.shape[0], Stars.shape[1], 2))
    for i in range(len(Stars)):
        star = Stars[i]
        lc = np.nansum(star, axis=(1, 2))
        lc[lc == 0] = np.nan
        lc = lc / np.nanmedian(lc)
        bads = np.nansum(lc > 1.2)
        if bads >= 10:
            flags[i] = 1
        for j in range(len(star)):
            if Trim == 0:
                c = centroid_com(star[j])
                ref = centroid_com(References[i])
            else:
                c = centroid_com(star[j, Trim:-Trim, Trim:-Trim])
                ref = centroid_com(References[i, Trim:-Trim, Trim:-Trim])
            c = c - ref
            centroids[i, j] = c
        if Plot:
            Plot_centroids(centroids[i], star, i)
    return centroids, flags
예제 #3
0
def get_centroids(fluxes,  centroid_shift=None, method='abs_distance',
                    check_outliers=False, showfig=False):
    '''
    fluxes: array, 3D fluxes
    method: str, (1) absolute distance (2) sklearn.ensemble
    centroid_shift: int, maximum shift in pixels; if larger then mask is flagged
    check_outliers: bool,
    '''
    xcen, ycen = [],[]
    mask = np.zeros(len(fluxes))

    if check_outliers:
        stacked = np.nansum(fluxes, axis=0)
        Xc, Yc = centroid_com(stacked)

    for idx,img in enumerate(fluxes):
        x,y = centroid_com(img)
        if check_outliers:
            if centroid_shift is not None:
                #shift = int(round(centroid_shift))
                shift = float(centroid_shift)
                if abs(Xc-x) > shift or abs(Yc-y) > shift:
                    mask[idx] = 1
            else:
                raise ValueError('`centroid_shift` not defined')
        else:
            pass
        xcen.append(x)
        ycen.append(y)

    #convert 0,1 into bool
    mask = np.array(mask, dtype=bool)

    if method == 'ensemble':
        X = np.c_[xcen,ycen]
        mask = IsolationForest(max_features=2, contamination=0.01).fit(X).predict(X)
        #output is 1 or -1, convert to bool
        mask = np.array([True if bool(i == 1.0) else False for i in mask])

    xcen, ycen = np.array(xcen),np.array(ycen)
    if showfig:
        if method == 'ensemble':
            pl.scatter(xcen, ycen, c=mask, cmap='RdBu')
        else:
            pl.plot(xcen,ycen,'bo',label='good data')
            pl.plot(xcen[mask],ycen[mask],'ro',label='bad data')
            pl.legend()

    return (xcen,ycen), mask
예제 #4
0
def center(s_post, member_indices):

    mem = gcat[member_indices]
    """ Member Galaxy Locations """

    mempix = convpix(mem, w)
    x = mempix[:, 0]
    y = mempix[:, 1]
    """ Configuring Pixel Space"""

    init_x, init_y = w.wcs_world2pix(s_post[0], s_post[1],
                                     1)  # initial estimate to draw box
    wid_arcsec = 302  # 5'x 5' area around s-post
    pix_scale = 0.8627  # "/pixel ---> 0.000239 deg/pixel
    wid_pixels = int(wid_arcsec / pix_scale)  # ~350x350 pixels

    xmin = int(init_x - (wid_pixels / 2.0))  # boundaries
    xmax = int(init_x + (wid_pixels / 2.0))
    ymin = int(init_y - (wid_pixels / 2.0))
    ymax = int(init_y + (wid_pixels / 2.0))
    """ 2D-Histogram & Smoothing """

    binstep = 10  # 10 pixel ~ 8.62 "
    wght = np.asarray(
        gcat[member_indices]['fch1'])  # weights: irac ch1[3.6 um] flux
    xedges = np.arange(xmin, xmax + binstep, binstep)
    yedges = np.arange(ymin, ymax + binstep, binstep)
    h, xedges, yedges = np.histogram2d(x,
                                       y,
                                       bins=(xedges, yedges),
                                       weights=wght)

    size = int(round(
        (np.shape(h)[0]) / 4.0))  # kernel size : at least ~ 4 times smaller
    stdev_ker = size / 3.0  # size = 3-sigma
    gauss_kernel = Gaussian2DKernel(stddev=stdev_ker, x_size=size,
                                    y_size=size)  # kernel
    smoothed_data_gauss = convolve_fft(h.T,
                                       gauss_kernel)  # convolution/smoothing
    """ Finds Peak """

    x_org, y_org = (xedges[0] + xedges[1]) / 2.0, (
        yedges[0] + yedges[1]) / 2.0  # origin of bin-coordinate
    fp_m = find_peaks(smoothed_data_gauss, 0,
                      npeaks=1)  # 1 peak with max value
    xbin_peak, ybin_peak = fp_m['x_peak'][0], fp_m['y_peak'][
        0]  # x, y positions of the peak
    x_p, y_p = (x_org + xbin_peak * binstep), (
        y_org + ybin_peak * binstep)  # conversion to pixel coordinates
    peak = (x_p, y_p)
    ra_p, dec_p = w.wcs_pix2world(peak[0], peak[1], 1)
    peak_fk5 = (ra_p, dec_p)
    """ Centroid from Image Moments """

    cen_pos = centroid_com(smoothed_data_gauss)
    cenx, ceny = (x_org + cen_pos[0] * binstep), (y_org + cen_pos[1] * binstep)
    ra_c, dec_c = w.wcs_pix2world(cenx, ceny, 1)
    centre = (ra_c, dec_c)

    return centre, peak_fk5
def plot_image():
    std = np.std(stamp[stamp == stamp])
    x1, y1 = centroid_com(stamp)
    x2, y2 = centroid_1dg(stamp)
    x3, y3 = centroid_2dg(stamp)
    return [((x1 - dx + xcen), (x2 - dx + xcen), (x3 - dx + xcen)),
            ((y1 - dy + ycen), (y2 - dy + ycen), (y3 - dy + ycen))]
예제 #6
0
def plot_aper_mask(fluxes,rad,aper_shape,contrast=0.1,epic=None):
    stacked = np.nansum(fluxes,axis=0)
    mask = make_mask(fluxes, rad = rad, shape=aper_shape)
    y,x = centroid_com(stacked)

    fig, ax = pl.subplots(1,1)
    interval = ZScaleInterval(contrast=contrast)
    zmin,zmax = interval.get_limits(stacked)

    cb = ax.imshow(stacked, origin='bottom', interpolation=None)
    ax.imshow(mask, alpha=0.3)
    if aper_shape == 'round':
        circ = pl.Circle((x,y),rad,color='w',alpha=0.2,lw=5,label='r={}'.format(rad))
        ax.add_artist(circ)

    ax.plot(x,y,'r+',ms=20, lw=10,label='centroid')
    pl.colorbar(cb, ax=ax)
    pl.xlabel('X')
    pl.ylabel('Y')
    pl.legend()
    if epic is not None:
        pl.title('EPIC {}'.format(epic))
    pl.show()

    return fig
예제 #7
0
def psfpy(data):
    x1, y1 = centroid_com(data)
    x2, y2 = centroid_1dg(data)
    x3, y3 = centroid_2dg(data)
    #    print(data)
    #    print(x1,y1,x2,y2,x3,y3)
    #    mean, median, std = sigma_clipped_stats(data, sigma=3.0, iters=5)
    #    data -= median    # subtract background
    cat = data_properties(data)
    #        print (cat)
    #列输出
    columns = [
        'id', 'xcentroid', 'ycentroid', 'semimajor_axis_sigma',
        'semiminor_axis_sigma', 'orientation', 'cxx', 'cyy', 'cxy',
        'eccentricity'
    ]
    tbl = cat.to_table(columns=columns)
    tbl['cxy'].info.format = '.10f'
    eccef = float(tbl['eccentricity'])
    str1 = str(tbl['semimajor_axis_sigma'])
    semimajorf = str1.split("[")[1].split("]")[0]
    str1 = str(tbl['semiminor_axis_sigma'])
    semiminorf = str1.split("[")[1].split("]")[0]
    str1 = str(tbl['orientation'])
    orientationf = str1.split("[")[1].split("]")[0]
    str1 = str(tbl['cxx'])
    cxxf = str1.split("[")[1].split("]")[0]
    str1 = str(tbl['cxy'])
    cxyf = str1.split("[")[1].split("]")[0]
    str1 = str(tbl['cyy'])
    cyyf = str1.split("[")[1].split("]")[0]
    return (x1, y1, x2, y2, x3, y3, semimajorf, semiminorf, eccef,
            orientationf, cxxf, cxyf, cyyf)
예제 #8
0
def plot_image(posx, posy, count, prevstds):
    #We have to redefine the stamp every time, otherwise the program doesn't woek
    stamp = data[i][int(round(posy - dy)):int(round(posy + dy)),
                    int(round(posx - dx)):int(round(posx + dx))]
    #this is just to keep track of how much recursing we do
    count = count + 1

    std = np.std(stamp[stamp == stamp])
    x1, y1 = centroid_com(stamp)
    x2, y2 = centroid_1dg(stamp)
    x3, y3 = centroid_2dg(stamp)
    xavg = np.average([x2, x3])
    yavg = np.average([y2, y3])
    xstd = np.std([x2, x3])
    ystd = np.std([y2, y3])
    #xavg = np.average([x1,x2,x3])
    #yavg = np.average([y1,y2,y3])
    #xstd = np.std([x1,x2,x3])
    #ystd = np.std([y1,y2,y3])
    #print(count, posx-dx+xavg, posy-dy+yavg, xstd, ystd)
    # RECURSION BITCH limit 100 times, while either std is higher than our 0.1 threshold
    # and as long as the std is getting smaller
    if (xstd + ystd > prevstds[0] + prevstds[1]):
        return posx, posy, prevstds[0]**(-2), prevstds[1]**(-2), count - 1
    if count < 100 and (xstd > 0.1 or ystd > 0.1) and (xstd <= prevstds[0] and
                                                       ystd <= prevstds[1]):
        return plot_image(posx - dx + xavg, posy - dy + yavg, count,
                          [xstd, ystd])
    else:
        return posx - dx + xavg, posy - dy + yavg, 1 / (xstd**2), 1 / (
            ystd**2), count
예제 #9
0
    def Select_Target(self, image, x, y, box):

        X = []
        Y = []

        #delete previous circles
        for elem in self.redcircle:
            self.canvas.delete(elem)

        D = image[int(y) - box:int(y) + box, int(x) - box:int(x) + box]

        xn, yn = centroid_com(D - numpy.median(D))
        xn = xn + int(x) - box
        yn = yn + int(y) - box

        print('Center of the target: x = {} y = {}'.format(xn, yn))

        X.append(xn)
        Y.append(yn)

        NX = X[0] - 22
        NY = Y[0]
        D = image[int(NY) - box:int(NY) + box, int(NX) - box:int(NX) + box]
        xn, yn = centroid_com(D - numpy.median(D))
        xn = xn + int(NX) - box
        yn = yn + int(NY) - box

        X.append(xn)
        Y.append(yn)

        for xe, ye in zip(X, Y):
            self.redcircle.append(
                self.canvas.create_oval(xe * self.zoom - 10,
                                        ye * self.zoom - 10,
                                        xe * self.zoom + 10,
                                        ye * self.zoom + 10,
                                        outline='blue',
                                        width=2))
            self.redcircle.append(
                self.canvas.create_oval(xe * self.zoom - 1,
                                        ye * self.zoom - 1,
                                        xe * self.zoom + 1,
                                        ye * self.zoom + 1,
                                        outline='red',
                                        width=2))
        self.Tx[self.index] = X
        self.Ty[self.index] = Y
예제 #10
0
    def psf_norm_2d(array, fwhm, size, threshold, mask_core, full_output,
                    verbose):
        """ 2d case """
        if size is not None:
            if size < array.shape[0]:
                psfs = frame_crop(array, size, force=True, verbose=False)
            else:
                psfs = array.copy()
        else:
            psfs = array.copy()

        # we check if the psf is centered and fix it if needed
        cy, cx = frame_center(psfs, verbose=False)
        xcom, ycom = photutils.centroid_com(psfs)
        if not (np.allclose(cy, ycom, atol=1e-2) or
                np.allclose(cx, xcom, atol=1e-2)):
            # first we find the centroid and put it in the center of the array
            centry, centrx = fit_2d(psfs)
            shiftx, shifty = centrx - cx, centry - cy
            psfs = frame_shift(array, -shifty, -shiftx, imlib=imlib,
                               interpolation=interpolation)
            if size is not None:
                psfs = frame_crop(psfs, size, force=True, verbose=False)

            for _ in range(2):
                centry, centrx = fit_2d(psfs)
                cy, cx = frame_center(psfs, verbose=False)
                shiftx, shifty = centrx - cx, centry - cy
                psfs = frame_shift(psfs, -shifty, -shiftx, imlib=imlib,
                                   interpolation=interpolation)

        # we check whether the flux is normalized and fix it if needed
        fwhm_aper = photutils.CircularAperture((frame_center(psfs)), fwhm/2)
        fwhm_aper_phot = photutils.aperture_photometry(psfs, fwhm_aper,
                                                       method='exact')
        fwhm_flux = np.array(fwhm_aper_phot['aperture_sum'])

        if fwhm_flux > 1.1 or fwhm_flux < 0.9:
            psf_norm_array = psfs / np.array(fwhm_aper_phot['aperture_sum'])
        else:
            psf_norm_array = psfs

        if threshold is not None:
            psf_norm_array[np.where(psf_norm_array < threshold)] = 0

        if mask_core is not None:
            psf_norm_array = get_circle(psf_norm_array, radius=mask_core)

        if verbose:
            print("Flux in 1xFWHM aperture: {:.3f}".format(fwhm_flux[0]))

        if full_output:
            return psf_norm_array, fwhm_flux, fwhm
        else:
            return psf_norm_array
예제 #11
0
def centroid(a):
    top=19
    bot=12
    
    a = ma.masked_invalid(a)
    #a=sigma_clip(a, sigma=7, iters=1)    
    a=a[bot:top+1, bot:top+1]
    a2=np.multiply(a,a)
    beta_np=np.sum(a)**2/np.sum(a2)
    xcg, ycg = centroid_2dg(a)+bot
    xc, yc = centroid_com(a)+bot
    return xc,yc, xcg, ycg   
예제 #12
0
def get_planicentre(img,
                    rad,
                    iterations=1,
                    croppix=400,
                    Debug=False,
                    endcrop=10):
    croppedimg = img

    for i in range(iterations):
        imgcent = centroid_com(croppedimg)

        if Debug:
            print(imgcent)
            plt.figure(figsize=(5, 5))
            im5 = plt.imshow(croppedimg, cmap=col)
            plt.axhline(imgcent[0], color=xcol)
            plt.axvline(imgcent[1], color=xcol)
            plt.title('Partial Image ' + str(i))
            plt.colorbar(im5)
            plt.show()

        croppedimg = croppedimg[(int(imgcent[1] - croppix)):(int(imgcent[1] +
                                                                 croppix)),
                                (int(imgcent[0] - croppix)):(int(imgcent[0] +
                                                                 croppix))]
        croppedimg = image.exp_despike(croppedimg, nsigma=1)
        croppix = croppix / 3

    planicentre1 = centroid_com(croppedimg)
    DiscImg = croppedimg[(int(planicentre1[1]) -
                          (int(rad) + endcrop)):(int(planicentre1[1]) +
                                                 (int(rad) + endcrop)),
                         (int(planicentre1[0]) -
                          (int(rad) + endcrop)):int(planicentre1[0]) +
                         ((int(rad) + endcrop))]
    planicentre2 = get_disc(DiscImg, r0=rad)
    return DiscImg, planicentre2
예제 #13
0
def plot_image():
    std = np.std(stamp[stamp==stamp])
    plt.imshow(stamp, interpolation='nearest', origin = 'lower', vmin = -1.*std, vmax = 3.*std, cmap='bone')
    plt.tick_params(axis='both', which='major', labelsize=8)
    circle0 = plt.Circle((dx,dy),0.1)
    x1, y1 = centroid_com(stamp)
    circle1 = plt.Circle((x1,y1),0.1,color='r')
    ax.add_artist(circle1)
    x2, y2 = centroid_1dg(stamp)
    circle2 = plt.Circle((x2,y2),0.1,color='b')
    ax.add_artist(circle2)
    x3, y3 = centroid_2dg(stamp)
    circle3 = plt.Circle((x3,y3),0.1,color='g')
    ax.add_artist(circle3)
    return ((x1, y1),(x2, y2),(x3, y3))
예제 #14
0
파일: phot.py 프로젝트: jpdeleon/moscatel
def get_centroid(image, method='com'):
    '''
    centroid_com(): Calculates the object 'center of mass' from 2D image moments.
    centroid_1dg(): Calculates the centroid by fitting 1D Gaussians to the marginal x and y distributions of the data.
    centroid_2dg(): Calculates the centroid by fitting a 2D Gaussian to the 2D distribution of the data.
    Default is centroid_2dg.
    '''
    if method == 'com':
        x, y = centroid_com(image)

    elif method == '1d_gaussian':
        x, y = centroid_1dg(image)

    else:  #default
        x, y = centroid_2dg(image)

    return (x, y)
예제 #15
0
def make_mask(fluxes, rad=None, cutoff_limit=1.0, shape='round', epic=None, showfig=False):
    '''
    create mask given 3D (t x h x w) fluxes
    '''
    #stack images
    stacked = np.nansum(fluxes,axis=0)

    #get centroid of stacked image
    x,y = centroid_com(stacked)
    xx,yy = int(round(x)), int(round(y))

    mask = np.zeros_like(stacked)

    if shape == 'square':
        if rad is not None:
            if stacked.size > (2*rad)**2:
                assert ValueError('mask size bigger than tpf cutout')
            for i in np.arange(-rad,rad,1):
                for j in np.arange(-rad,rad,1):
                    mask[xx+i,yy+j] = 1
        else:
            raise ValueError('rad: aperture radius not defined')

    elif shape == 'irregular':
        mask = find_aperture(fluxes, cutoff_limit=1.0)

    elif shape == 'round' or shape == 'cirle':
        #default: round
        if rad is not None:
            if stacked.size > (2*rad)**2:
                assert ValueError('mask size bigger than tpf cutout')
            for i in range(stacked.shape[0]):
                for j in range(stacked.shape[1]):
                    if np.sqrt((xx-i)**2+(yy-j)**2)<=rad:
                        mask[i,j] = 1
        else:
            raise ValueError('rad: aperture radius not defined')
    else:
        # no mask; use all pixels
        mask = np.ones_like(stacked)

    if showfig:
        fig = plot_aper_mask(fluxes,rad,aper_shape=shape,contrast=0.1,epic=epic)

    return np.array(mask,dtype=bool)
예제 #16
0
def plot_image(posx,posy, count, prevstds):
    stamp = data[int(round(posy-dy)):int(round(posy+dy)), int(round(posx-dx)):int(round(posx+dx))]

    count = count +1

    std = np.std(stamp[stamp==stamp])
    x1, y1 = centroid_com(stamp)
    x2, y2 = centroid_1dg(stamp)
    x3, y3 = centroid_2dg(stamp)
    xavg = np.average([x1,x2,x3])
    yavg = np.average([y1,y2,y3])
    xstd = np.std([x1,x2,x3])
    ystd = np.std([y1,y2,y3])

    # RECURSION BITCH
    if count < 100 and (xstd > 0.1 or ystd > 0.1) and (xstd <= prevstds[0] and ystd <= prevstds[1]):
        print(count, posx-dx+xavg, posy-dy+yavg, xstd, ystd)
        return plot_image(posx-dx+xavg, posy-dy+yavg, count, [xstd,ystd])
    else:
        return posx-dx+xavg, posy-dy+yavg, 1/(xstd**2), 1/(ystd**2), count
예제 #17
0
def get_centroid(image, method='com'):
    '''
    centroid_com(): Calculates the object “center of mass” from 2D image moments.
    centroid_1dg(): Calculates the centroid by fitting 1D Gaussians to the marginal x and y distributions of the data.
    centroid_2dg(): Calculates the centroid by fitting a 2D Gaussian to the 2D distribution of the data.
    Default is com.
    '''
    if method == 'com':
        x, y = centroid_com(image)
        return (x, y)

    elif method == '1d_gaussian':
        x, y = centroid_1dg(image)
        return (x, y)
    elif method == '2d_gaussian':
        #bug: takes too much time; fit may be unsuccessful
        x, y = centroid_2dg(image)
        return (x, y)
    else:
        print('invalid centroiding algorithm')
        sys.exit()
예제 #18
0
def recenter(image, pos, window_size=5, method="1dg"):
    """
    Recenter each star in each frame of the image cube before performing
    aperture photometry to take care of slight misalignments between frames
    because of atmospheric turbulence and tracking/pointing errors.

    Parameters
    ----------
    image : numpy array
        2D image

    pos : list
        List of (x,y) tuples for star positions

    window_size : int
        Window size in which to fit the gaussian to the star to calculate
        new center

    method : string
        Method used to find center of the star. Options are 1d Gaussian fit,
        2d gaussian fit or com (center of mass)

    Returns
    -------
    xcen, ycen : float
        Source x and y centers
    """
    pos = np.asarray(pos)

    ny, nx = image.shape
    window_size = int(window_size)
    nstars = pos.shape[0]

    star_pos = np.zeros([nstars, 2], dtype=np.float32)
    for i in range(nstars):
        x, y = pos[i][0], pos[i][1]

        xmin, xmax = int(x) - int(window_size / 2), int(x) + int(
            window_size / 2) + 1
        ymin, ymax = int(y) - int(window_size / 2), int(y) + int(
            window_size / 2) + 1

        if xmin < 0:
            xmin = 0

        if ymin < 0:
            ymin = 0

        if xmax > nx:
            xmax = nx

        if ymax > ny:
            ymax = ny

        if method == "1dg":
            xcen, ycen = centroid_1dg(image[ymin:ymax, xmin:xmax])
        elif method == "2dg":
            xcen, ycen = centroid_2dg(image[ymin:ymax, xmin:xmax])
        elif method == "com":
            xcen, ycen = centroid_com(image[ymin:ymax, xmin:xmax])

        if (np.abs(xmin + xcen - x)) > 3. or (np.abs(ymin + ycen - y)) > 3.:
            star_pos[i, 0] = x
            star_pos[i, 1] = y
        else:
            star_pos[i, 0] = xmin + xcen
            star_pos[i, 1] = ymin + ycen

    return star_pos
예제 #19
0
def find_center(image, center_guess, cutout_size=30, max_iters=10):
    """
    Find the centroid of a star from an initial guess of its position. Originally
    written to find star from a mouse click.

    Parameters
    ----------

    image : numpy array or CCDData
        Image containing the star.

    center_guess : array or tuple
        The position, in pixels, of the initial guess for the position of
        the star. The coordinates should be horizontal first, then vertical,
        i.e. opposite the usual Python convention for a numpy array.

    cutout_size : int, optional
        The default width of the cutout to use for finding the star.

    max_iters : int, optional
        Maximum number of iterations to go through in finding the center.
    """
    pad = cutout_size // 2
    x, y = center_guess

    # Keep track of iterations
    cnt = 0

    # Grab the cutout...
    sub_data = image[y - pad:y + pad, x - pad:x + pad]  # - med

    # ...do stats on it...
    _, sub_med, _ = sigma_clipped_stats(sub_data)
    # sub_med = 0

    # ...and centroid.
    x_cm, y_cm = centroid_com(sub_data - sub_med)

    # Translate centroid back to original image (maybe use Cutout2D instead)
    cen = np.array([x_cm + x - pad, y_cm + y - pad])

    # ceno is the "original" center guess, set it to something nonsensical here
    ceno = np.array([-100, -100])

    while (cnt <= max_iters and (np.abs(np.array([x_cm, y_cm]) - pad).max() > 3
                                 or np.abs(cen - ceno).max() > 0.1)):

        # Update x, y positions for subsetting
        x = int(np.floor(x_cm)) + x - pad
        y = int(np.floor(y_cm)) + y - pad
        sub_data = image[y - pad:y + pad, x - pad:x + pad]  # - med
        _, sub_med, _ = sigma_clipped_stats(sub_data)
        # sub_med = 0
        mask = (sub_data - sub_med) < 0
        x_cm, y_cm = centroid_com(sub_data - sub_med, mask=mask)
        ceno = cen
        cen = np.array([x_cm + x - pad, y_cm + y - pad])
        if not np.all(~np.isnan(cen)):
            raise RuntimeError('Centroid finding failed, '
                               'previous was {}, current is {}'.format(
                                   ceno, cen))
        cnt += 1

    return cen
def plot_image():
    std = np.std(stamp[stamp == stamp])
    x1, y1 = centroid_com(stamp)
    x2, y2 = centroid_1dg(stamp)
    x3, y3 = centroid_2dg(stamp)
    return np.array([[x1, x2, x3], [y1, y2, y3]])
예제 #21
0
    def center(iter_no, s_post, member_indices, apr, plotmap):

        mem = gcat[
            member_indices]  # gcat = The galaxy catalog of which the overdensities are being computed.
        """ Member Galaxy Locations in Pixel Space """

        galpix = convpix(mem, w)
        x = galpix[:, 0]
        y = galpix[:, 1]
        """ Configuring Pixel Space"""

        init_x, init_y = w.wcs_world2pix(s_post[0], s_post[1],
                                         0)  # initial estimate to draw box
        PIX_SCALE = imagefile[0].header[
            'CDELT2'] * 3600.0  # "/pixel ---> 0.000239 deg/pixel, IRAC/bootes

        if apr <= 2.0:
            wid_arcsec = 302  # ~5'x5' region around the signpost
        elif 2.0 < apr <= 5.0:
            wid_arcsec = 716.5  # ~12'x12'
        else:
            wid_arcsec = 898  # ~15'x15'

        wid_pixels = int(wid_arcsec /
                         PIX_SCALE)  # ~350x350 pixels/ 830x830 /1040x1040
        xmin, xmax = int(init_x - (wid_pixels / 2.0)), int(
            init_x + (wid_pixels / 2.0))  # boundaries
        ymin, ymax = int(init_y - (wid_pixels / 2.0)), int(init_y +
                                                           (wid_pixels / 2.0))
        """ 2D-Histogram & Smoothing """

        binstep = 5.0  # 10 pixel ~ 8.62 "
        wght = np.asarray(
            gcat[member_indices]['ch2_flux'])  # weights: irac ch2[4.5 um] flux
        xedges = np.arange(xmin, xmax + binstep, binstep)
        yedges = np.arange(ymin, ymax + binstep, binstep)
        h, xedges, yedges = np.histogram2d(x,
                                           y,
                                           bins=(xedges, yedges),
                                           weights=wght)

        xmid = [(xedges[ik] + xedges[ik + 1]) / 2.0
                for ik in range(len(xedges) - 1)]
        ymid = [(yedges[ij] + yedges[ij + 1]) / 2.0
                for ij in range(len(yedges) - 1)]

        size = int(round((np.shape(h)[0]) /
                         4.0))  # kernel size : at least ~ 4 times smaller
        stdev_ker = size / 4.0  # size = 4-sigma
        gauss_kernel = Gaussian2DKernel(x_stddev=stdev_ker,
                                        y_stddev=stdev_ker,
                                        x_size=size,
                                        y_size=size)  # kernel
        smoothed_data_gauss = convolve_fft(
            h.T, gauss_kernel)  # convolution/smoothing
        max_sm_val = max(smoothed_data_gauss.flatten())
        """ Finds Peak """

        x_org, y_org = (xedges[0] + xedges[1]) / 2.0, (
            yedges[0] + yedges[1]) / 2.0  # origin of bin-coordinate
        fp_m = find_peaks(smoothed_data_gauss, 0,
                          npeaks=1)  # 1 peak with max value
        xbin_peak, ybin_peak = fp_m['x_peak'][0], fp_m['y_peak'][
            0]  # x, y positions of the peak
        x_p, y_p = (x_org + xbin_peak * binstep), (
            y_org + ybin_peak * binstep)  # conversion to pixel coordinates
        peak_pix = (x_p, y_p)
        ra_p, dec_p = w.wcs_pix2world(peak_pix[0], peak_pix[1], 0)
        peak_fk5 = (ra_p, dec_p)
        """ Centroid from Image Moments """

        cen_pos = centroid_com(smoothed_data_gauss)
        cenx, ceny = (x_org + cen_pos[0] * binstep), (y_org +
                                                      cen_pos[1] * binstep)
        ra_c, dec_c = w.wcs_pix2world(cenx, ceny, 0)
        centre = (ra_c, dec_c)
        """ Plots """

        if plotmap == 'ON':
            fgm = plt.figure()
            ax = fgm.add_subplot(111)
            # ax_b.imshow(smoothed_data_gauss, extent=[xmin, xmax, ymin, ymax], cmap='jet')
            cntf = ax.contourf(
                xmid,
                ymid,
                smoothed_data_gauss,
                cmap='Blues',
                levels=[lt for lt in np.arange(0.10, max_sm_val + 0.02, 0.02)])
            ax.scatter(x, y, marker='o', color='red', s=5)
            ax.scatter(cenx, ceny, marker='s')
            ax.scatter(x_p, y_p, marker='^')
            ax.scatter(init_x, init_y, marker='o', color='lime')

            fgm.colorbar(cntf)
            fgm.savefig(catdir + 'clump_plots/' + str(iter_no) + '_map.png',
                        format='png',
                        dpi=100)
            plt.close(fgm)

        return centre, peak_fk5
예제 #22
0
파일: fit_2d.py 프로젝트: pierfra-r/VIP
def fit_2dmoffat(array,
                 crop=False,
                 cent=None,
                 cropsize=15,
                 fwhm=4,
                 threshold=False,
                 sigfactor=6,
                 full_output=True,
                 debug=True):
    """ Fitting a 2D Moffat to the 2D distribution of the data.

    Parameters
    ----------
    array : numpy ndarray
        Input frame with a single PSF.
    crop : bool, optional
        If True an square sub image will be cropped.
    cent : tuple of int, optional
        X,Y integer position of source in the array for extracting the subimage.
        If None the center of the frame is used for cropping the subframe (the
        PSF is assumed to be ~ at the center of the frame).
    cropsize : int, optional
        Size of the subimage.
    fwhm : float, optional
        Initial values for the FWHM of the fitted 2d Moffat, in px.
    threshold : bool, optional
        If True the background pixels (estimated using sigma clipped statistics)
        will be replaced by small random Gaussian noise.
    sigfactor : int, optional
        The background pixels will be thresholded before fitting a 2d Moffat
        to the data using sigma clipped statistics. All values smaller than
        (MEDIAN + sigfactor*STDDEV) will be replaced by small random Gaussian
        noise.
    full_output : bool, optional
        If False it returns just the centroid, if True also returns the
        FWHM in X and Y (in pixels), the amplitude and the rotation angle.
    debug : bool, optional
        If True, the function prints out parameters of the fit and plots the
        data, model and residuals.

    Returns
    -------
    mean_y : float
        Source centroid y position on input array from fitting.
    mean_x : float
        Source centroid x position on input array from fitting.

    If ``full_output`` is True it returns a Pandas dataframe containing the
    following columns:
    'alpha': Float value. Alpha parameter.
    'amplitude' : Float value. Moffat Amplitude.
    'centroid_x' : Float value. X coordinate of the centroid.
    'centroid_y' : Float value. Y coordinate of the centroid.
    'fwhm' : Float value. FHWM [px].
    'gamma' : Float value. Gamma parameter.

    """
    check_array(array, dim=2, msg='array')

    if crop:
        if cent is None:
            ceny, cenx = frame_center(array)
        else:
            cenx, ceny = cent

        imside = array.shape[0]
        psf_subimage, suby, subx = get_square(array,
                                              min(cropsize, imside),
                                              ceny,
                                              cenx,
                                              position=True)
    else:
        psf_subimage = array.copy()

    if threshold:
        _, clipmed, clipstd = sigma_clipped_stats(psf_subimage, sigma=2)
        indi = np.where(psf_subimage <= clipmed + sigfactor * clipstd)
        subimnoise = np.random.randn(psf_subimage.shape[0],
                                     psf_subimage.shape[1]) * clipstd
        psf_subimage[indi] = subimnoise[indi]

    # Creating the 2D Moffat model
    init_amplitude = np.ptp(psf_subimage)
    xcom, ycom = photutils.centroid_com(psf_subimage)
    moffat = models.Moffat2D(amplitude=init_amplitude,
                             x_0=xcom,
                             y_0=ycom,
                             gamma=fwhm / 2.,
                             alpha=1)
    # Levenberg-Marquardt algorithm
    fitter = fitting.LevMarLSQFitter()
    y, x = np.indices(psf_subimage.shape)
    fit = fitter(moffat, x, y, psf_subimage)

    if crop:
        mean_y = fit.y_0.value + suby
        mean_x = fit.x_0.value + subx
    else:
        mean_y = fit.y_0.value
        mean_x = fit.x_0.value

    fwhm = fit.fwhm
    amplitude = fit.amplitude.value
    alpha = fit.alpha.value
    gamma = fit.gamma.value

    if debug:
        if threshold:
            label = ('Subimage thresholded', 'Model', 'Residuals')
        else:
            label = ('Subimage', 'Model', 'Residuals')
        plot_frames((psf_subimage, fit(x, y), psf_subimage - fit(x, y)),
                    grid=True,
                    grid_spacing=1,
                    label=label)
        print('FWHM =', fwhm)
        print('centroid y =', mean_y)
        print('centroid x =', mean_x)
        print('centroid y subim =', fit.y_0.value)
        print('centroid x subim =', fit.x_0.value, '\n')
        print('amplitude =', amplitude)
        print('alpha =', alpha)
        print('gamma =', gamma)

    # compute uncertainties
    if fitter.fit_info['param_cov'] is not None:
        perr = np.sqrt(np.diag(fitter.fit_info['param_cov']))
        amplitude_err, mean_x_err, mean_y_err, gamma_err, alpha_err = perr
        fwhm_err = 2 * gamma_err
    else:
        amplitude_err, mean_x_err, mean_y_err = None, None, None
        gamma_err, alpha_err, fwhm_err = None, None, None

    if full_output:
        return pd.DataFrame(
            {
                'centroid_y': mean_y,
                'centroid_x': mean_x,
                'fwhm': fwhm,
                'alpha': alpha,
                'gamma': gamma,
                'amplitude': amplitude,
                'centroid_y_err': mean_y_err,
                'centroid_x_err': mean_x_err,
                'fwhm_err': fwhm_err,
                'alpha_err': alpha_err,
                'gamma_err': gamma_err,
                'amplitude_err': amplitude_err
            },
            index=[0])
    else:
        return mean_y, mean_x
예제 #23
0
def fit_2dairydisk(array,
                   crop=False,
                   cent=None,
                   cropsize=15,
                   fwhm=4,
                   threshold=False,
                   sigfactor=6,
                   full_output=False,
                   debug=False):
    """ Fitting a 2D Moffat to the 2D distribution of the data.

    Parameters
    ----------
    array : array_like
        Input frame with a single PSF.
    crop : bool, optional
        If True an square sub image will be cropped.
    cent : tuple of int, optional
        X,Y integer position of source in the array for extracting the subimage.
        If None the center of the frame is used for cropping the subframe (the
        PSF is assumed to be ~ at the center of the frame).
    cropsize : int, optional
        Size of the subimage.
    fwhm : float, optional
        Initial values for the FWHM of the fitted 2d Moffat, in px.
    threshold : bool, optional
        If True the background pixels (estimated using sigma clipped statistics)
        will be replaced by small random Gaussian noise.
    sigfactor : int, optional
        The background pixels will be thresholded before fitting a 2d Moffat
        to the data using sigma clipped statistics. All values smaller than
        (MEDIAN + sigfactor*STDDEV) will be replaced by small random Gaussian
        noise.
    full_output : bool, optional
        If False it returns just the centroid, if True also returns the
        FWHM in X and Y (in pixels), the amplitude and the rotation angle.
    debug : bool, optional
        If True, the function prints out parameters of the fit and plots the
        data, model and residuals.

    Returns
    -------
    mean_y : float
        Source centroid y position on input array from fitting.
    mean_x : float
        Source centroid x position on input array from fitting.

    If ``full_output`` is True it returns a Pandas dataframe containing the
    following columns:
    'alpha': Float value. Alpha parameter.
    'amplitude' : Float value. Moffat Amplitude.
    'centroid_x' : Float value. X coordinate of the centroid.
    'centroid_y' : Float value. Y coordinate of the centroid.
    'fwhm' : Float value. FHWM [px].
    'gamma' : Float value. Gamma parameter.

    """
    if array.ndim != 2:
        raise TypeError('Input array is not a frame or 2d array')

    if crop:
        if cent is None:
            ceny, cenx = frame_center(array)
        else:
            cenx, ceny = cent

        imside = array.shape[0]
        psf_subimage, suby, subx = get_square(array,
                                              min(cropsize, imside),
                                              ceny,
                                              cenx,
                                              position=True)
    else:
        psf_subimage = array.copy()

    if threshold:
        _, clipmed, clipstd = sigma_clipped_stats(psf_subimage, sigma=2)
        indi = np.where(psf_subimage <= clipmed + sigfactor * clipstd)
        subimnoise = np.random.randn(psf_subimage.shape[0],
                                     psf_subimage.shape[1]) * clipstd
        psf_subimage[indi] = subimnoise[indi]

    # Creating the 2d Airy disk model
    init_amplitude = np.ptp(psf_subimage)
    xcom, ycom = photutils.centroid_com(psf_subimage)
    diam_1st_zero = (fwhm * 2.44) / 1.028
    airy = models.AiryDisk2D(amplitude=init_amplitude,
                             x_0=xcom,
                             y_0=ycom,
                             radius=diam_1st_zero / 2.)
    # Levenberg-Marquardt algorithm
    fitter = fitting.LevMarLSQFitter()
    y, x = np.indices(psf_subimage.shape)
    fit = fitter(airy, x, y, psf_subimage)

    if crop:
        mean_y = fit.y_0.value + suby
        mean_x = fit.x_0.value + subx
    else:
        mean_y = fit.y_0.value
        mean_x = fit.x_0.value

    amplitude = fit.amplitude.value
    radius = fit.radius.value
    fwhm = ((radius * 1.028) / 2.44) * 2

    if debug:
        if threshold:
            msg = ['Subimage thresholded', 'Model', 'Residuals']
        else:
            msg = ['Subimage', 'Model', 'Residuals']
        pp_subplots(psf_subimage,
                    fit(x, y),
                    psf_subimage - fit(x, y),
                    grid=True,
                    gridspacing=1,
                    label=msg)
        print('FWHM =', fwhm)
        print('centroid y =', mean_y)
        print('centroid x =', mean_x)
        print('centroid y subim =', fit.y_0.value)
        print('centroid x subim =', fit.x_0.value, '\n')
        print('amplitude =', amplitude)
        print('radius =', radius)

    if full_output:
        return pd.DataFrame(
            {
                'centroid_y': mean_y,
                'centroid_x': mean_x,
                'fwhm': fwhm,
                'radius': radius,
                'amplitude': amplitude
            },
            index=[0])
    else:
        return mean_y, mean_x
예제 #24
0
def fit_2dgaussian(array,
                   crop=False,
                   cent=None,
                   cropsize=15,
                   fwhmx=4,
                   fwhmy=4,
                   theta=0,
                   threshold=False,
                   sigfactor=6,
                   full_output=False,
                   debug=False):
    """ Fitting a 2D Gaussian to the 2D distribution of the data.

    Parameters
    ----------
    array : array_like
        Input frame with a single PSF.
    crop : bool, optional
        If True an square sub image will be cropped.
    cent : tuple of int, optional
        X,Y integer position of source in the array for extracting the subimage.
        If None the center of the frame is used for cropping the subframe (the
        PSF is assumed to be ~ at the center of the frame).
    cropsize : int, optional
        Size of the subimage.
    fwhmx, fwhmy : float, optional
        Initial values for the standard deviation of the fitted Gaussian, in px.
    theta : float, optional
        Angle of inclination of the 2d Gaussian counting from the positive X
        axis.
    threshold : bool, optional
        If True the background pixels (estimated using sigma clipped statistics)
        will be replaced by small random Gaussian noise.
    sigfactor : int, optional
        The background pixels will be thresholded before fitting a 2d Gaussian
        to the data using sigma clipped statistics. All values smaller than
        (MEDIAN + sigfactor*STDDEV) will be replaced by small random Gaussian
        noise.
    full_output : bool, optional
        If False it returns just the centroid, if True also returns the
        FWHM in X and Y (in pixels), the amplitude and the rotation angle.
    debug : bool, optional
        If True, the function prints out parameters of the fit and plots the
        data, model and residuals.

    Returns
    -------
    mean_y : float
        Source centroid y position on input array from fitting.
    mean_x : float
        Source centroid x position on input array from fitting.

    If ``full_output`` is True it returns a Pandas dataframe containing the
    following columns:
    'amplitude' : Float value. Amplitude of the Gaussian.
    'centroid_x' : Float value. X coordinate of the centroid.
    'centroid_y' : Float value. Y coordinate of the centroid.
    'fwhm_x' : Float value. FHWM in X [px].
    'fwhm_y' : Float value. FHWM in Y [px].
    'theta' : Float value. Rotation angle.

    """
    if array.ndim != 2:
        raise TypeError('Input array is not a frame or 2d array')

    if crop:
        if cent is None:
            ceny, cenx = frame_center(array)
        else:
            cenx, ceny = cent

        imside = array.shape[0]
        psf_subimage, suby, subx = get_square(array,
                                              min(cropsize, imside),
                                              ceny,
                                              cenx,
                                              position=True)
    else:
        psf_subimage = array.copy()

    if threshold:
        _, clipmed, clipstd = sigma_clipped_stats(psf_subimage, sigma=2)
        indi = np.where(psf_subimage <= clipmed + sigfactor * clipstd)
        subimnoise = np.random.randn(psf_subimage.shape[0],
                                     psf_subimage.shape[1]) * clipstd
        psf_subimage[indi] = subimnoise[indi]

    # Creating the 2D Gaussian model
    init_amplitude = np.ptp(psf_subimage)
    xcom, ycom = photutils.centroid_com(psf_subimage)
    gauss = models.Gaussian2D(amplitude=init_amplitude,
                              theta=theta,
                              x_mean=xcom,
                              y_mean=ycom,
                              x_stddev=fwhmx * gaussian_fwhm_to_sigma,
                              y_stddev=fwhmy * gaussian_fwhm_to_sigma)
    # Levenberg-Marquardt algorithm
    fitter = fitting.LevMarLSQFitter()
    y, x = np.indices(psf_subimage.shape)
    fit = fitter(gauss, x, y, psf_subimage)

    if crop:
        mean_y = fit.y_mean.value + suby
        mean_x = fit.x_mean.value + subx
    else:
        mean_y = fit.y_mean.value
        mean_x = fit.x_mean.value
    fwhm_y = fit.y_stddev.value * gaussian_sigma_to_fwhm
    fwhm_x = fit.x_stddev.value * gaussian_sigma_to_fwhm
    amplitude = fit.amplitude.value
    theta = np.rad2deg(fit.theta.value)

    if debug:
        if threshold:
            msg = ['Subimage thresholded', 'Model', 'Residuals']
        else:
            msg = ['Subimage', 'Model', 'Residuals']
        pp_subplots(psf_subimage,
                    fit(x, y),
                    psf_subimage - fit(x, y),
                    grid=True,
                    gridspacing=1,
                    label=msg)
        print('FWHM_y =', fwhm_y)
        print('FWHM_x =', fwhm_x, '\n')
        print('centroid y =', mean_y)
        print('centroid x =', mean_x)
        print('centroid y subim =', fit.y_mean.value)
        print('centroid x subim =', fit.x_mean.value, '\n')
        print('amplitude =', amplitude)
        print('theta =', theta)

    if full_output:
        return pd.DataFrame(
            {
                'centroid_y': mean_y,
                'centroid_x': mean_x,
                'fwhm_y': fwhm_y,
                'fwhm_x': fwhm_x,
                'amplitude': amplitude,
                'theta': theta
            },
            index=[0])
    else:
        return mean_y, mean_x
예제 #25
0
def center(s_post, member_cat, image_wcs, apr, dog, itr_no):

    mem = member_cat
    mempix = convpix(mem, image_wcs)  # member objects in pixel coordinates
    x_pixels, y_pixels = mempix[:, 0], mempix[:, 1]

    init_x, init_y = image_wcs.wcs_world2pix(s_post[0], s_post[1],
                                             0)  # initial estimate to draw box
    dogx, dogy = image_wcs.wcs_world2pix(dog[0], dog[1],
                                         0)  # DOG location in pixel space
    pix_scale = 0.000239631 * 3600.  # "/pixel IRAC-Ch2/SDWFS survey

    if apr <= 2.0:
        wid_arcsec = 200.0  # ~6'x6' region around the DOG
    elif 2.0 < apr <= 5.0:
        wid_arcsec = 716.5  # ~12'x12'
    else:
        wid_arcsec = 898.0  # ~15'x15'

    wid_pixels = int(
        wid_arcsec / pix_scale
    )  # ~350x350 pixels/~830x830 /~1040x1040 depending on aperture.
    xmin, xmax = int(dogx - (wid_pixels / 2.0)), int(
        dogx + (wid_pixels / 2.0))  # boundaries
    ymin, ymax = int(dogy - (wid_pixels / 2.0)), int(
        dogy + (wid_pixels / 2.0))  # boundaries

    # 2D-histogram
    resol = 5  # (input in arcsec -- > degrees) resol is the grid resolution for histogram.
    binstep = int(resol / pix_scale)  # of image pixels in one bin
    bnsx = list(np.arange(xmin, xmax + binstep,
                          binstep))  # bin-edges in X direction
    bnsy = list(np.arange(ymin, ymax + binstep,
                          binstep))  # bin-edges in Y direction
    nx_bins, ny_bins = len(bnsx), len(bnsy)  # number of bins in the histogram
    wght = np.asarray(mem['fch2'])  # weights: irac ch2[4.5 um] flux

    h, xedges, yedges = np.histogram2d(x_pixels,
                                       y_pixels,
                                       bins=[bnsx, bnsy],
                                       weights=wght)
    mesh_pixels = np.meshgrid(xedges, yedges)
    mesh_wcs = image_wcs.wcs_pix2world(mesh_pixels[0], mesh_pixels[1], 0)

    # Smoothing
    size = int(round(
        (np.shape(h)[0]) / 4.0))  # kernel size : at least ~ 4 times smaller
    stdev_ker = size / 4.0  # size = 4-sigma
    gauss_kernel = Gaussian2DKernel(x_stddev=stdev_ker,
                                    y_stddev=stdev_ker,
                                    x_size=size,
                                    y_size=size)  # kernel
    smoothed_data_gauss = convolve_fft(h.T,
                                       gauss_kernel)  # convolution/smoothing

    # Centroid of the image moments
    x_org, y_org = (xedges[0] + xedges[1]) / 2.0, (
        yedges[0] + yedges[1]) / 2.0  # origin of bin-coordinate
    cen_pos = centroid_com(smoothed_data_gauss)
    cenx, ceny = (x_org + cen_pos[0] * binstep), (y_org + cen_pos[1] * binstep)
    centre = image_wcs.wcs_pix2world(cenx, ceny, 0)

    dist_to_dog = sky_sep(s_post, dog)
    print(round(dist_to_dog, 2))
    """ Plotting """

    fig = plt.figure(figsize=(5, 5), dpi=300, tight_layout=True)
    ax = fig.add_subplot(111, projection=image_wcs)
    max_sm_val = max(smoothed_data_gauss.flatten())
    ax.contourf(
        mesh_wcs[0][1:, :-1],
        mesh_wcs[1][:-1, :-1],
        smoothed_data_gauss,
        interpolation="nearest",
        origin='lower',
        cmap='viridis',
        extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]],
        levels=[lt for lt in np.arange(-0.10, max_sm_val + 0.30, 0.20)],
        transform=ax.get_transform('icrs'))
    ax.scatter(mem['ra'],
               mem['dec'],
               marker='o',
               s=50,
               transform=ax.get_transform('icrs'),
               facecolor='red',
               edgecolor='none',
               alpha=1.,
               zorder=4,
               label='Member Galaxies')

    circ = Circle((init_x, init_y), (apr * 60) / pix_scale,
                  edgecolor='w',
                  facecolor='none',
                  lw=2.0,
                  ls='--')
    ax.add_patch(circ)
    ax.plot(centre[0],
            centre[1],
            marker='x',
            color='k',
            fillstyle='none',
            ls='',
            ms=15,
            label='Centroid',
            mew=2.0,
            transform=ax.get_transform('icrs'))
    ax.plot(dog[0],
            dog[1],
            marker='o',
            color='lime',
            fillstyle='full',
            ls='',
            ms=8,
            label='DOG',
            mew=4.0,
            transform=ax.get_transform('icrs'))
    ax.text(dog[0] - 0.002,
            dog[1] - 0.019,
            r'$\mathrm{{Richness~={val}}}$'.format(val=len(mem)),
            transform=ax.get_transform('icrs'),
            fontsize=20,
            color='w')
    ax.text(dog[0] - 0.01,
            dog[1] - 0.015,
            r'$\mathrm{{Iteration~={val2}}}$'.format(val2=itr_no + 1),
            transform=ax.get_transform('icrs'),
            fontsize=15,
            color='w')

    # Accessories

    ax.set_xlim(xmin, xmax - binstep)
    ax.set_ylim(ymin, ymax - binstep)

    ax.coords[0].set_ticks_position('b')
    ax.coords[0].set_ticklabel_position('b')
    ax.coords[0].set_axislabel_position('b')

    ax.coords[1].set_ticks_position('l_dict')
    ax.coords[1].set_ticklabel_position('l_dict')
    ax.coords[1].set_axislabel_position('l_dict')

    ax.coords[0].set_ticks(
        np.arange(mesh_wcs[0][-1][-1], mesh_wcs[0][-1][0] + 0.02, 0.02) *
        units.degree)
    ax.coords[0].set_ticklabel(fontsize=10)
    ax.coords[0].set_major_formatter('d.dd')
    ax.coords[0].set_axislabel(r'$\mathrm{R.A.(J2000)}$', fontsize=13)

    ax.coords[1].set_ticks(
        np.arange(mesh_wcs[1][:, 0][0], mesh_wcs[1][:, 0][-1] + 0.02, 0.02) *
        units.degree)
    ax.coords[1].set_ticklabel(fontsize=10.0)
    ax.coords[1].set_major_formatter('d.dd')
    ax.coords[1].set_axislabel(r'$\mathrm{Dec.(J2000)}$', fontsize=13)
    ax.legend(loc='best', fontsize=10)
    plt.axis('off')
    fig.show()
    fig.savefig(anim_dir + 'itr' + str(itr_no + 1) + '.png', format='png')
    plt.close(fig)

    return centre
예제 #26
0
    def get_centroid_cutout(self,
                            x,
                            y,
                            box_size=30,
                            method="howell",
                            dao_fwhm=10.,
                            dao_SNR=100.,
                            plot=False,
                            plot_full=False,
                            stretch=None):
        """
        Perform centroiding on a cutout window.
        
        INPUT:
            x -  a touple 
            y - 
            box_size -  the total box size in pixels
            method   -  the centroiding method to use for cutout. This can be
                            "centroid_2dg"
                            "centroid_com"
                            "daofind"
        OUTPUT:
            centroid positions
        
        EXAMPLE:
            PM = PhotoMetry(filenames[0])
            PM.perform_photometry()
            print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="daofind",plot=True))
            print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_com",plot=True))
            print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_2dg",plot=True))

            print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="daofind",box_size=50,stretch="HistEqStretch"))
            print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_com",plot=True,box_size=50))
            print(PM.get_centroid_cutout(234.227204448,25.6594515323,method="centroid_2dg",plot=True,box_size=50))
        """
        int_x = int(round(x))
        int_y = int(round(y))
        postage_stamp = photutils.utils.cutouts.cutout_footprint(
            self.data, (int_x, int_y), box_size)

        # Only interested in the image data [1] is the mask
        postage_stamp = np.array(postage_stamp[0])
        #plt.imshow(postage_stamp)

        #print(postage_stamp)
        if method == "centroid_2dg":
            x_stamp_centroid, y_stamp_centroid = photutils.centroid_com(
                postage_stamp)
        elif method == "centroid_com":
            x_stamp_centroid, y_stamp_centroid = photutils.centroid_2dg(
                postage_stamp)
        elif method == "daofind":
            daofind = DAOStarFinder(fwhm=dao_fwhm,
                                    threshold=dao_SNR * self.bkg_sigma)
            sources = daofind(postage_stamp)
            positions = (sources['xcentroid'], sources['ycentroid'])
            x_stamp_centroid, y_stamp_centroid = float(positions[0]), float(
                positions[1])
        elif method == "howell":
            x_stamp_centroid, y_stamp_centroid = self.howell_center(
                postage_stamp)
        else:
            print(
                "Error: method must be 'daofind', centroid_2dg', 'centroid_com' or 'howell'"
            )
            pass
        x_centroid = x_stamp_centroid + int_x - box_size / 2.
        y_centroid = y_stamp_centroid + int_y - box_size / 2.
        if plot:
            fig, ax = plt.subplots()
            if stretch:
                norm = gkastro.stretch_data(postage_stamp, method=stretch)
            else:
                norm = None
            ax.imshow(postage_stamp,
                      origin="lower",
                      extent=[
                          int_x - box_size / 2., int_x + box_size / 2.,
                          int_y - box_size / 2., int_y + box_size / 2.
                      ],
                      interpolation="none",
                      norm=norm)
            ax.set_xlim(int_x - box_size / 2., int_x + box_size / 2.)
            ax.set_ylim(int_y - box_size / 2., int_y + box_size / 2.)
            ax.set_xlabel("X pixel")
            ax.set_ylabel("Y pixel")
            ax.plot(x_centroid,
                    y_centroid,
                    color='#1f77b4',
                    marker="+",
                    ms=30,
                    mew=2)
        if plot_full:
            fig, ax = plt.subplots()
            ax.imshow(self.data, origin="lower")
            ax.plot(x_centroid,
                    y_centroid,
                    color='#1f77b4',
                    marker="+",
                    ms=30,
                    mew=2)
        return x_centroid, y_centroid
    def show_event(viewer, event, datax, datay):

        i = iw._viewer.get_image()
        data = i.get_data()
        pad = 15
        x = int(np.floor(event.data_x))
        y = int(np.floor(event.data_y))
        cnt = 0
        sub_data = data[y - pad:y + pad, x - pad:x + pad] #- med
        _, sub_med, _ = sigma_clipped_stats(sub_data)
        #sub_med = 0
        foo, moo = centroid_com(sub_data - sub_med)
        cenx = foo + x - pad
        ceny = moo + y - pad
        cen = np.array([foo + x - pad, moo + y - pad])
        ceno = np.array([-100, -100])
        while cnt <= 10 and (np.abs(np.array([foo, moo]) - pad).max() >3 or np.abs(cen - ceno).max() > 0.1):
           # print(cnt, foo, moo)
            x = int(np.floor(foo)) + x - pad
            y = int(np.floor(moo)) + y - pad
            sub_data = data[y - pad:y + pad, x - pad:x + pad] #- med
            _, sub_med, _ = sigma_clipped_stats(sub_data)
            #sub_med = 0
            mask = (sub_data - sub_med) < 0
            foo, moo = centroid_com(sub_data - sub_med, mask=mask)
            ceno = cen
            cen = np.array([foo + x - pad, moo + y - pad])
    #             print(cen)
    #             print(cen - ceno)
            cnt += 1

        iw.add_markers(Table(data=[[cen[0]], [cen[1]]], names=['x', 'y']))
        #print(foo, moo)
        yd, xd = np.indices((sub_data.shape))
        r = np.sqrt((xd - foo)**2 + (yd - moo)**2)
        r_exact = r.copy()
        r = r.astype(np.int)
        tbin = np.bincount(r.ravel(), sub_data.ravel())
        rbin = np.bincount(r.ravel(), r_exact.ravel())
        nr = np.bincount(r.ravel())
        radialprofile = tbin / nr
        ravg = rbin / nr
        adjust_max = radialprofile.max() - sub_med
        scaled_profile = (radialprofile - sub_med) / adjust_max
        scaled_exact_counts = (sub_data - sub_med) / adjust_max
        out.clear_output(wait=True)
        with out:
           # print(dir(event))
            #print(event.data_x, event.data_y)
            plt.clf()
            #sub_med += med
            seeing_plot(r_exact, scaled_exact_counts, ravg, scaled_profile, 5,
                    'Some Image Name', file_name='some_name', gap=6, annulus_width=13)
            plt.show()
        out2.clear_output(wait=True)
        with out2:
            tbin2 = np.bincount(r.ravel(), (sub_data - sub_med).ravel())
            counts = np.cumsum(tbin2)
            mag_diff = -2.5 * np.log10(counts/counts.max())
            plt.plot(range(len(radialprofile)), counts)
            plt.xlim(0, 20)
            #plt.ylim(0.2, 0)
            plt.grid()
            sub_blot = sub_data.copy()
            sub_blot[10:30, 10:30] = np.nan
            sub_std = np.nanstd(sub_blot)
            plt.title('Net counts in aperture std {:.2f} med {:.2f}'.format(sub_std, sub_med))
            sub_pois = (sub_data - sub_med)
            e_sky = np.sqrt(sub_med)
            rn = 10
            sub_noise_sq = np.sqrt(sub_pois ** 2 + sub_std ** 2) ** 2
            nbin = np.sqrt(np.bincount(r.ravel(), (sub_noise_sq).ravel()))
            plt.xlabel('Aperture radius')
            plt.show()
        out3.clear_output(wait=True)
        with out3:
            poisson = np.sqrt(np.cumsum(tbin2))
            error = np.sqrt(poisson ** 2 + np.cumsum(nr) * (e_sky ** 2 + rn ** 2))
            snr = np.cumsum(tbin2) / error
            snr_max = snr[:20].max()
            plt.plot(range(len(radialprofile)), snr)
            plt.title('Signal to noise ratio {}'.format(snr.max()))
            plt.xlim(0, 20)
            #plt.ylim(0, 2)
            plt.xlabel('Aperture radius')
            plt.grid()
            plt.show()
예제 #28
0
            # For the individual image cutouts
            fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(8, 4),
                                   sharey=True)

            # The actual work
            for j, star in enumerate(stars):
                crad = int(cutoutsize/2.)
                scutout = tdata[star[1]-crad:star[1]+crad,
                                star[0]-crad:star[0]+crad]

                im = ax[j].imshow(scutout, interpolation='none',
                                  origin='lower', norm=norm,
                                  vmin=0, vmax=200)

                # Actually calculate the centroid
                cen = centroid_com(scutout)
                # cen = centroid_2dg(scutout)

                cxseries[j, i] = cen[0]
                cyseries[j, i] = cen[1]

                # Plot the centroid on the image
                ax[j].scatter(cen[0], cen[1], color='green')

                print("\t\tStar%d: %f,%f" % (j, cen[0], cen[1]))

            # cbar = fig.colorbar(im, pad=0.05, orientation='vertical')
            if dnps is True:
                units = "DN/sec"
            else:
                units = "DN"
예제 #29
0
def center(s_post, gal_cat, image_wcs, search_box_width):

    # centroid of the gal_cat
    # search box width = width of the search box around the signpost in arcmin. (5' x 5' BOX)
    # image_wcs = WCS of the image where objects are detected.

    # Search box
    PIX_SCALE = 0.000239631 * 3600  # arcsec/pixel ; 0.000239631 degrees/pixel for IRAC-ch2 (SDWFS Survey)
    wid_arcsec = search_box_width * 60  # arcsec
    wid_pixels = int(wid_arcsec / PIX_SCALE)  # in pixels

    init_x, init_y = image_wcs.wcs_world2pix(
        s_post[0], s_post[1], 0)  # initial center estimate to draw box
    xmin, xmax = int(init_x - (wid_pixels / 2.0)), int(
        init_x + (wid_pixels / 2.0))  # boundaries
    ymin, ymax = int(init_y - (wid_pixels / 2.0)), int(
        init_y + (wid_pixels / 2.0))  # boundaries

    # Galaxy catalog in image pixel coordinates
    galpix = convpix(gal_cat, image_wcs)  # objects in pixel coordinates
    x_pixels, y_pixels = galpix[:, 0], galpix[:, 1]

    # 2D-histogram on the grid in the search box
    binstep = 5.0  # pixels, grid resolution
    wght = np.asarray(gal_cat['ch2'])  # weights: irac ch2[4.5 um] flux, uJy
    xedges, yedges = np.arange(xmin, xmax + binstep,
                               binstep), np.arange(ymin, ymax + binstep,
                                                   binstep)
    h, xedges, yedges = np.histogram2d(x_pixels,
                                       y_pixels,
                                       bins=(xedges, yedges),
                                       weights=wght)

    # Smoothing the 2D histogram of the galaxies in the search box
    size = int(round(
        (np.shape(h)[0]) / 4.0))  # kernel size : at least ~ 4 times smaller
    stdev_ker = size / 4.0  # size = 4-sigma
    gauss_kernel = Gaussian2DKernel(x_stddev=stdev_ker,
                                    y_stddev=stdev_ker,
                                    x_size=size,
                                    y_size=size)  # kernel
    smoothed_data_gauss = convolve_fft(h.T,
                                       gauss_kernel)  # convolution/smoothing

    # Peak of the histogram
    x_org, y_org = (xedges[0] + xedges[1]) / 2.0, (
        yedges[0] + yedges[1]) / 2.0  # origin of bin-coordinate
    fp_m = find_peaks(smoothed_data_gauss, 0,
                      npeaks=1)  # 1 peak with max value
    xbin_peak, ybin_peak = fp_m['x_peak'][0], fp_m['y_peak'][
        0]  # x, y positions of the peak
    x_p, y_p = (x_org + xbin_peak * binstep), (
        y_org + ybin_peak * binstep)  # conversion to pixel coordinates
    peak_fk5 = image_wcs.wcs_pix2world(x_p, y_p, 0)

    # Centroid of the image moments
    cen_pos = centroid_com(smoothed_data_gauss)
    cenx, ceny = (x_org + cen_pos[0] * binstep), (y_org + cen_pos[1] * binstep)
    centre = image_wcs.wcs_pix2world(cenx, ceny, 0)

    return centre, peak_fk5
예제 #30
0
# Set the approximate star coordinates of reference star chosen
estimated_star_x = [998,998,958]
estimated_star_y = [1161,1121,1121]
actual_star_x = [0,0,0] # dummy values
actual_star_y = [0,0,0]

for i in range(len(sciList)):
    HDUList = fits.open(procList[i], ignore_missing_end=True)
    procData = HDUList[0].data
    HDUList.close()
    (x0, x1) = (estimated_star_x[i]-20, estimated_star_x[i]+20) #create smaller area to cover the star
    (y0, y1) = (estimated_star_y[i]-20, estimated_star_y[i]+20)
    cutout = procData[y0:y1,x0:x1]
    mean, median, std = sigma_clipped_stats(cutout)
    cx, cy = photutils.centroid_com(cutout-median) #find the center position of the star
    actual_star_x[i] = cx+x0 #fill in actual calculated locations of star center from above
    actual_star_y[i] = cy+y0
    print('Image %s unshifted ref location:' % (i+1), actual_star_x[i], actual_star_y[i], '\n')

#offset images to match centroid locations

#default crop region
xmin, xmax = 50, 2050
ymin, ymax = 150, 2150
alignedImages = np.zeros((ymax-ymin, xmax-xmin, len(sciList))) #create empty array the size of [y pix, x pix, # images]

#calcualte the offset for each image and apply it then add to 3D array
for i in range(len(sciList)):
    xoffset = int(round(actual_star_x[i]-actual_star_x[0]))
    yoffset = int(round(actual_star_y[i]-actual_star_y[0]))