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
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)
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
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
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)