Example #1
0
def aperture_photometry_scan(data,
                             x_pos,
                             y_pos,
                             ap_width,
                             ap_length,
                             theta=0.0,
                             show=False,
                             plt_title=None):
    """Aperture photometry on source located on x_pos, y_pos with
    rectangular aperture of dimensions specified by ap_length, ap_width
    is used. Aperture sums are NOT sky subtracted.

    Parameters
    ----------
    data : `np.array`
        2D array of floats
    x_pos : float
        X position of source.
    y_pos : float
        Y position of source
    ap_width : int
        Width (along x axis) of photometric aperture.
    ap_length : int
        Length (along y axis) of photometric aperture.
    theta : float
        Angle of orientation (from x-axis) for aperture, in radians.
        Increases counter-clockwise.
    show : bool, optional
        If true, plot showing aperture(s) on source will pop up. Defaults to F.
    plt_title : str or None, optional
        Only used if `show` is True. Title for plot. Defaults to None.
    Returns
    -------
    phot_tab : `astropy.table`
        Table containing
    """

    copy_data = copy.copy(data)

    rect_ap = RectangularAperture((x_pos, y_pos),
                                  w=ap_width,
                                  h=ap_length,
                                  theta=theta)

    phot_table = aperture_photometry(copy_data, rect_ap, method='exact')
    if show:
        mask = rect_ap.to_mask(method='center')
        data_cutout = mask.cutout(data)
        plt.title(plt_title)
        z1, z2 = (-12.10630989074707, 32.53888328838081)
        plt.imshow(data, origin='lower', vmin=z1, vmax=z2)
        rect_ap.plot(color='white', lw=2)
        plt.show()
        plt.close()

    return phot_table
Example #2
0
def place_overlay(x_pixel, y_pixel, mousebutton, wcs, ax, FOV=1.5, Size='750'):
    """Places either the main CCD, or the guide CCD apeture overlay 
    centered on the pixel coordinates depending on the boolean case "guide"
    specified in the input arguments. The overlay for the guide camera is placed
    with respect to the CCD center. Function also replots image to reset apertures
    (Easiest way I could find to do it for now)
    """
    fov = FOV * 60
    size = int(Size)
    scale = fov / size
    #Set plate scale of image 60 is number of arcmin across

    position_Target = (size / 2, size / 2)
    aperture_Target = CircularAperture(position_Target, r=(PlateScale / scale))
    aperture_Target.plot(color='blue', lw=1.5, alpha=0.5)

    if x_pixel == None or y_pixel == None:
        position_CCD = (size / 2, size / 2)
        position_Guide = (size / 2 - GuideOffRA / scale,
                          ((size / 2) + (GuideOffDEC / scale)))
    else:
        if mousebutton:
            position_Guide = (x_pixel, y_pixel)
            position_CCD = ((x_pixel) + GuideOffRA / scale,
                            (y_pixel - (GuideOffDEC / scale)))
        else:
            position_Guide = (x_pixel - GuideOffRA / scale,
                              y_pixel + (GuideOffDEC / scale))
            position_CCD = ((x_pixel), (y_pixel))

    aperture_GuideStar = CircularAperture(position_Guide,
                                          r=(PlateScale / scale))
    aperture_Guide = RectangularAperture(position_Guide, (GuideX / scale),
                                         (GuideY / scale))
    aperture_GuideStar.plot(color='blue', lw=1.5, alpha=0.5)
    aperture_Guide.plot(color='red', lw=1.5, alpha=0.5)

    aperture_CCD = RectangularAperture(position_CCD, (SciX / scale),
                                       (SciY / scale))
    aperture_CCD.plot(color='green', lw=1.5, alpha=0.5)

    ax.figure.canvas.draw()

    coords = SkyCoord.from_pixel(position_CCD[0], position_CCD[1], wcs)
    RA_str = coords.ra.to_string(units.hour)
    DEC_str = coords.dec.to_string(units.degree)

    #print coords of main CCD center
    print(RA_str, DEC_str)
Example #3
0
def show_stamps(pscs,
                frame_idx=None,
                stamp_size=11,
                aperture_position=None,
                aperture_size=None,
                show_residual=False,
                stretch=None,
                save_name=None,
                show_max=False,
                show_pixel_grid=False,
                **kwargs):

    if aperture_position is None:
        midpoint = (stamp_size - 1) / 2
        aperture_position = (midpoint, midpoint)

    if aperture_size:
        aperture = RectangularAperture(aperture_position,
                                       w=aperture_size,
                                       h=aperture_size,
                                       theta=0)

    ncols = len(pscs)

    if show_residual:
        ncols += 1

    nrows = 1

    fig = Figure()
    FigureCanvas(fig)
    fig.set_figheight(4)
    fig.set_figwidth(8)

    if frame_idx is not None:
        s0 = pscs[0][frame_idx]
        s1 = pscs[1][frame_idx]
    else:
        s0 = pscs[0]
        s1 = pscs[1]

    if stretch == 'log':
        stretch = LogStretch()
    else:
        stretch = LinearStretch()

    norm = ImageNormalize(s0, interval=MinMaxInterval(), stretch=stretch)

    ax1 = fig.add_subplot(nrows, ncols, 1)

    im = ax1.imshow(s0, cmap=get_palette(), norm=norm)

    if aperture_size:
        aperture.plot(color='r', lw=4, ax=ax1)
        # annulus.plot(color='c', lw=2, ls='--', ax=ax1)

    # create an axes on the right side of ax. The width of cax will be 5%
    # of ax and the padding between cax and ax will be fixed at 0.05 inch.
    # https://stackoverflow.com/questions/18195758/set-matplotlib-colorbar-size-to-match-graph
    divider = make_axes_locatable(ax1)
    cax = divider.append_axes("right", size="5%", pad=0.05)
    fig.colorbar(im, cax=cax)
    ax1.set_title('Target')

    # Comparison
    ax2 = fig.add_subplot(nrows, ncols, 2)
    im = ax2.imshow(s1, cmap=get_palette(), norm=norm)

    if aperture_size:
        aperture.plot(color='r', lw=4, ax=ax1)
        # annulus.plot(color='c', lw=2, ls='--', ax=ax1)

    divider = make_axes_locatable(ax2)
    cax = divider.append_axes("right", size="5%", pad=0.05)
    fig.colorbar(im, cax=cax)
    ax2.set_title('Comparison')

    if show_pixel_grid:
        add_pixel_grid(ax1, stamp_size, stamp_size, show_superpixel=False)
        add_pixel_grid(ax2, stamp_size, stamp_size, show_superpixel=False)

    if show_residual:
        ax3 = fig.add_subplot(nrows, ncols, 3)

        # Residual
        residual = s0 - s1
        im = ax3.imshow(residual,
                        cmap=get_palette(),
                        norm=ImageNormalize(residual,
                                            interval=MinMaxInterval(),
                                            stretch=LinearStretch()))

        divider = make_axes_locatable(ax3)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        fig.colorbar(im, cax=cax)
        ax3.set_title('Noise Residual')
        ax3.set_title('Residual RMS: {:.01%}'.format(residual.std()))
        ax3.set_yticklabels([])
        ax3.set_xticklabels([])

        if show_pixel_grid:
            add_pixel_grid(ax1, stamp_size, stamp_size, show_superpixel=False)

    # Turn off tick labels
    ax1.set_yticklabels([])
    ax1.set_xticklabels([])
    ax2.set_yticklabels([])
    ax2.set_xticklabels([])

    if save_name:
        try:
            fig.savefig(save_name)
        except Exception as e:
            warn("Can't save figure: {}".format(e))

    return fig
Example #4
0
def asymmetric_elongated_aperture_photom(scidata, starts, inverted, jpeg='', plot=False, sat_adu = 16383, spectral_band='G'):
    '''
    Compute photometry using rectangular apertures.
    This is a good method to use for "April 2014" de Bruijn encoding
    '''
    logger = logging.getLogger()
    
    logger.debug(f'science image is dimensions: {np.shape(scidata)}')
    
    match, factor = table_matches_image(starts, scidata)
    if not match:
        logger.warning(f'table data does not match image data. Dividing table coordinates by a factor of {factor:.2f} to table data (spectral band is {spectral_band})')
        starts['x_image'] /= factor
        starts['y_image'] /= factor
    
    positions, radii, thetas = aperture_centers_weighted_start_differential(starts)

    # get median pixel value inside the fireball bounding box
    median_bckgnd = np.median(get_bounding_box(scidata, starts))


    if plot:
        plt.close()
        fig = plt.gcf()
        ax = fig.gca()
        plt.imshow(jpeg, cmap=plt.cm.gray)

    starts['aperture_sum'] = np.nan
    starts['bckgng_sub_measurements'] = np.nan
    starts['SNR'] = np.nan
    starts['signal'] = np.nan
    starts['exp_time'] = np.nan
    starts['aperture_sum_err'] = np.nan
    starts['aperture_sum_err_plus'] = np.nan
    starts['aperture_sum_err_minus'] = np.nan
    starts['aperture_saturated'] = False

    for i in range(len(starts)-1):
        starts[i]['exp_time'] = LC_open_time(starts, i, i+1, inverted)

    for el, pos, radius, theta in zip(starts[:-1], positions, radii, thetas):
        
        #zero_order_light = scidata[int(pos[1])][int(pos[0])]
        
        aperture = RectangularAperture(pos, w=radius*2, h=7.*2, theta=theta) # 7
        
        # determine if any of the pixels in the aperture have reached saturation level,
        # flag accordingly
        aperture_mask = aperture.to_mask('center')
        aperture_values = aperture_mask.multiply(scidata)
        if np.any(aperture_values == sat_adu):
            el['aperture_saturated'] = True
        
        
        # do photometry
        aperture_result = aperture_photometry(scidata, aperture, method='subpixel', subpixels=16)
        
        
        el['aperture_sum'] = aperture_result['aperture_sum'].data
        #el['aperture_sum_err'] = aperture_result['aperture_sum_err'].data TODO FIXME
        
        el['bckgng_sub_measurements'] = el['aperture_sum'] -  aperture.area*median_bckgnd
        el['SNR'] = el['aperture_sum'] / np.sqrt(el['aperture_sum'] + aperture.area*median_bckgnd)
        el['aperture_sum_err_plus'] = 1/el['SNR']
        el['aperture_sum_err_minus'] = 1/el['SNR']
        if plot:
            aperture.plot(color='white')


    
    if plot:
        #min_x, min_y, max_x, max_y = get_bounds([p['x_image'] for p in points], pos2)
        ax.set_xlim([np.min(starts['x_image']), np.max(starts['x_image'])])
        ax.set_ylim([np.min(starts['y_image']), np.max(starts['y_image'])])
        
        full_path = starts.meta['self_file_name']
        dirname = os.path.dirname(full_path)
        basename = os.path.basename(full_path).split('.')[0]
        fname = os.path.join(dirname, basename + "_aperture_photometry_"+spectral_band+".jpg")
        plt.savefig(fname, dpi=150)

    return starts
Example #5
0
class ApertureSet(object):
    """Set of apertures for the photometry"""

    # (I'm not sure if I want to stick with photutils, since that
    # currently enforces the same aperture size for all
    # apertures. Either way, we separate the apertures list out from
    # the individual image.

    def __init__(self, perpendic=False):

        # control variable
        self.perpendic = perpendic

        # Some parameters for aperture construction
        self.rectWidth = 220.
        self.rectHeight = 90.
        self.rectTheta = np.radians(325.)

        # sky rectangles
        self.skyWidth = np.copy(self.rectWidth)
        self.skyHeight = np.copy(self.rectHeight)

        # sky nudge
        self.skyNudge = np.array([0., 30.])

        if self.perpendic:
            self.rectTheta = np.radians(55.)
            self.skyNudge = np.array([120., 130.])

        # some default positions for apertures
        self.aperCens = np.array([])
        self.skyCens = np.array([])

        # INCLUDE ENTRIES FOR THE SKY REGIONS!!!

    def setDefaultCenters(self):
        """Sets up default aperture centers for testing on the
        2017-04-14 Jupiter data"""

        # the third one is a dummy to help me get the array dimensions
        # the right way round...
        vX = np.array([944., 892., 1105., 693., 1297.])
        vY = np.array([520., 446., 365., 592., 250.5])

        if self.perpendic:
            vX = np.array([960., 885., 1100., 772., 1285.])
            vY = np.array([456., 509., 381., 588., 264.0])

        self.aperCens = np.vstack((vX, vY))

        # set up the sky apertures
        self.skyCens = np.copy(self.aperCens)

        # DO THE OFFSET HERE.
        self.skyCens[1] -= (self.skyNudge[1] + self.skyHeight)
        self.skyCens[0] -= self.skyNudge[0]

        if not self.perpendic:
            self.skyCens[1, 1] += 2.0 * (self.skyNudge[1] + self.skyHeight)
        # self.skyCens[1,0] += 2.0 * (self.skyNudge[1] + self.skyHeight)

    def buildApertures(self):
        """Builds the apertures from the centers"""

        if np.size(self.aperCens) < 1:
            return

        self.apersObj = RectangularAperture(positions=self.aperCens, \
                                                w=self.rectWidth, \
                                                h=self.rectHeight, \
                                                theta=self.rectTheta)

        self.apersSky = RectangularAperture(positions=self.skyCens, \
                                                w=self.rectWidth, \
                                                h=self.rectHeight, \
                                                theta=self.rectTheta)

    def showApertures(self, figNum=1, inAx=None):
        """Uses photutils apertures built-in to show the apertures"""

        # This is a really stupid cargo-cult way to proceed... Come
        # back to this later!!

        if not inAx:
            fig = plt.figure(figNum)
            fig.clf()
            ax = fig.add_subplot(111)
            ax.plot([0., 1024], [0., 1024], 'w.', alpha=0.)
        else:
            ax = inAx

        self.apersObj.plot(ax=ax, color='g', alpha=0.7)
        self.apersSky.plot(ax=ax, color='b', ls='--', alpha=0.7)