def show_sources(data, sources): """ Convenience method for plotting the identified sources Parameters ---------- data : FITS data to plot sources : Sources found in the FITS data Returns ------- """ fig, ax = plt.subplots(nrows=1, ncols=1) norm = ImageNormalize(data, stretch=LinearStretch(), interval=ZScaleInterval()) im = ax.imshow(data, norm=norm, cmap='gray', origin='lower') # Make apertures apertures = CircularAperture((sources['xcentroid'], sources['ycentroid']),r=3) apertures.plot(color='red', lw=1.5, alpha=0.75) ax.grid(False) fig.savefig('example_image.png', format='png', dpi=275) plt.show()
def plot_peaks(box, x_peaks, y_peaks, radius=None, title=None, vmin=None, vmax=None): """ This function plots the data with peaks marked ... :param box: :param x_peaks: :param y_peaks: :return: """ # Determine the maximum value in the box and the minium value for plotting if vmin is None: vmin = max(np.nanmin(box), 0.) if vmax is None: vmax = 0.5 * (np.nanmax(box) + vmin) # Set the normalization norm = ImageNormalize(stretch=SqrtStretch()) # Make the plot plt.figure(figsize=(8,2.5)) plt.imshow(box, origin='lower', norm=norm, interpolation='nearest', vmin=vmin, vmax=vmax, cmap="viridis") if radius is None: plt.plot(x_peaks, y_peaks, ls='none', color='white', marker='+', ms=40, lw=10, mew=4) else: positions = (x_peaks, y_peaks) apertures = CircularAperture(positions, r=radius) apertures.plot(color='green', lw=1.5, alpha=0.5) plt.xlim(0, box.shape[1]-1) plt.ylim(0, box.shape[0]-1) if title is not None: plt.title(title) plt.show()
def photometry(self,filepath, b, d): hdulist = fits.open(filepath, ignore_missing_end=True) hdu = hdulist[0] hdu.data.shape image = hdu.data.astype(float) image -= np.median(image) bkg_sigma = mad_std(image) daofind = DAOStarFinder(fwhm=b, threshold=d * bkg_sigma) sources = daofind(image) # Save Stellar Sources from DOA Star Algorithm for col in sources.colnames: sources[col].info.format = '%.8g' # for consistent table output print(sources) # Perform Aperture Photometry positions = (sources['xcentroid'], sources['ycentroid']) apertures = CircularAperture(positions, r=17.) phot_table = aperture_photometry(image, apertures) for col in phot_table.colnames: phot_table[col].info.format = '%.8g' # for consistent table output filedest1 = input("Where to Save the result:") filedest2 = input("Where to Save the result 2:") print(phot_table) np.savetxt(filedest1, (sources), delimiter=',') # Save Result in CSV np.savetxt(filedest2, (phot_table), delimiter=',') # Save Result in CSV plt.imshow(image, cmap='gray_r', origin='lower') apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.show()
def plot_sources(sources, ax, **kwargs): """ DEPRECATED Helper function to plot sources nicely over a map WARNING : sources should respect astropy convention : x and y reversed Parameters ---------- sources : :class:`~pandas:pandas.DataFrame` a Pandas Dataframe containing at least columns 'xcentroid' and 'ycentroid' ax : :class:`~plt:matplotlib.axes.Axes` The matplotlib axes on which to plot (should be containing the map on top of which we are going to plot the sources) kwargs : dict any keyword argument accepted by :func:`photutils:photutils.CircularAperture.plot` Returns ------- fig : :class:`~plt:matplotlib.figure.Figure` The figure containing the plot. ax : :class:`~plt:matplotlib.axes.Axes` The axes containing the plot. """ f = ax.get_figure() positions=(sources['ycentroid'], sources['xcentroid']) apertures = CircularAperture(positions, r=4.) color = kwargs.pop('c', 'red') color = kwargs.pop('color', color) lw = kwargs.pop('lw', 1.5) alpha = kwargs.pop('alpha', 0.5) apertures.plot(color=color, lw=lw, alpha=alpha, ax=ax, **kwargs) return f,ax
def plot(self, top_n=0, figsize=(20,10), cmap='gray_r'): ''' Plot the found stars in the image. If top_n is set to a value > 0, plot only top_n brightest stars. Parameters: - top_n (int): number of brightest stars to plot - figsize (tuple): size of the image - cmap (str): color map to plotted, default is inverted gray ''' if top_n > 0: sources = self.top_n(top_n) else: sources = self.sources positions = np.transpose((sources['xcentroid'], sources['ycentroid'])) apertures = CircularAperture(positions, r=4.) plt.figure(figsize=figsize) plt.imshow(self.img, cmap=cmap) for i in sources.index: label = sources.peak[i] plt.annotate(label, (sources.xcentroid[i], sources.ycentroid[i])) apertures.plot(color='b', lw=1.5, alpha=0.5)
def takePicture(): img = cv2.imread('output/20201024013736_ZWO_ASI294MC_Pro.tiff') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) mean, median, std = sigma_clipped_stats(gray, sigma=3.0) print(f'mean:{mean} median:{median} std:{std}') daofind = DAOStarFinder(fwhm=5.0, threshold=5. * std) print(gray.shape, median.shape) sources = daofind(gray - median) for col in sources.colnames: sources[col].info.format = '%.8g' # for consistent table output print(sources) import numpy as np import matplotlib.pyplot as plt from astropy.visualization import SqrtStretch from astropy.visualization.mpl_normalize import ImageNormalize from photutils import CircularAperture positions = np.transpose((sources['xcentroid'], sources['ycentroid'])) apertures = CircularAperture(positions, r=4.) norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(gray, cmap='Greys', origin='lower', norm=norm, interpolation='nearest') apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.savefig('kk.png') cv2.namedWindow('Falcon') cv2.imshow('Falcon', gray) cv2.waitKey(0) return
def ap_phot(sources, data, source_r=6., sky_in=15, sky_out=20, plot=False): global fig centroids = (sources['xcentroid'], sources['ycentroid']) source_aperture = CircularAperture(centroids, r=source_r) source_area = source_aperture.area() source_table = aperture_photometry(data, source_aperture) sky_aperture = CircularAnnulus(centroids, r_in=sky_in, r_out=sky_out) sky_area = sky_aperture.area() sky_table = aperture_photometry(data, sky_aperture) sky_subtracted_source = deepcopy(source_table) for i in range(np.shape(centroids)[1]): sky_value = sky_table[i][3] sky_per_pix = sky_value / sky_area sky_behind_source = sky_per_pix * source_area sky_subtracted_source[i][3] -= sky_behind_source if plot: fig = plt.figure(figsize=(17, 17)) plt.imshow(data, cmap='gray', origin='lower', vmin=0, vmax=1500) for i in range(np.shape(centroids)[1]): plt.annotate(str(source_table[i][0]), xy=(np.float64(source_table[i][1]) + 15., np.float64(source_table[i][2]) + 15.), color="white") source_aperture.plot(color='blue', lw=1.5, alpha=0.5) sky_aperture.plot(color="orange", lw=0.5, alpha=0.5) plt.tight_layout() plt.show() return sky_subtracted_source
def plot_it( star_lists: List[StarDescriptionList], sizes: List[float], random_offset: List[bool], fits_data: List[float], wcs, title, padding: int = PADDING, annotate=True, ): fig, data = get_plot_with_background_data(fits_data, padding, title) logging.debug(f"plotting {[len(x) for x in star_lists]} stars per color") positions = [] for stars in star_lists: stars = add_pixels(stars, wcs, PADDING) positions.append([(o.xpos, o.ypos) for o in stars]) from itertools import cycle cycol = cycle("rgbcmyk") for idx, pos in enumerate(positions): if len(pos) > 0: apps = CircularAperture(pos, r=sizes[idx]) apps.plot(color=next(cycol), lw=1.5, alpha=0.5) random.seed(42) if annotate: for idx, star in enumerate(star_lists): annotate_it(star, -10, 15, random_offset=random_offset[idx], size=10) return fig
def fit_cluster(positions, star_list, image, clust, plot_directory): X_train = [(s.pos[0], s.pos[1], s.m1(), s.BV_col()) for s in star_list] clf = mixture.GaussianMixture(n_components=2, covariance_type='full') clf.fit(X_train) labels = clf.predict(X_train) fig, ax = plt.subplots(nrows = 1, ncols = 1, figsize=(12,16)) plt.title('Gaussian Mixture Classified Stars') maximum = np.quantile(image.flatten(), 0.99) plt.imshow(image, cmap='gray', interpolation='nearest', vmin = 0, vmax = maximum) star_list_trunc = None for component in range(0,2): apertures = CircularAperture([positions[i] for i, l in enumerate(labels) if l == component], r=4.) if component == 1: star_list_trunc = [star_list[i] for i, l in enumerate(labels) if l == component] apertures.plot(color='red', lw=1.5) else: apertures.plot(color='blue', lw=1.5) fig.savefig(plot_directory + clust + '_classified.pdf', dpi=300, bbox_inches='tight') plt.close(fig) covariance = clf.covariances_[0][0:2, 0:2] eigen_vals = np.linalg.eig(covariance)[0] Casp = np.sqrt(abs(eigen_vals[0] - eigen_vals[1])/(eigen_vals[0] + eigen_vals[1])) return Casp, star_list_trunc
def try_dao(fitsfile, outfile='out.png'): hdulist = fits.open(fitsfile) hdu = hdulist[0] if len(hdu.data.shape) == 3: data = hdu.data[0] else: data = hdu.data mean, median, std = sigma_clipped_stats(data[800:900, 800:900], sigma=3.0, iters=5) print(mean, median, std) #data = hdu.data sources = daofind(data - median, fwhm=3.0, threshold=5. * std) print 'Found %i sources' % len(sources) positions = (sources['xcentroid'], sources['ycentroid']) apertures = CircularAperture(positions, r=4.) norm = ImageNormalize(stretch=SqrtStretch(), vmin=2000, vmax=3000) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) plt.title('%i Sources from a single all-sky frame' % len(sources)) apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.savefig(filename=outfile)
def plot_light_curves(diff_cube, unique_extracted_objects): frame_data = [i for i in range(len(diff_cube))] colors = [(random.uniform(0.5, 1),random.uniform(0.5, 1),random.uniform(0.5,1)) for i in range(len(unique_extracted_objects))] plt.figure(figsize=(20,10)) for i, extracted_obj in enumerate(unique_extracted_objects): ap_data=[] plt.figure(i, figsize=(10, 12)) for frame in diff_cube: diff_cube_test = frame.copy() flux, fluxerr, flag = sep.sum_ellipse(diff_cube_test, x=extracted_obj[0], y=extracted_obj[1], a=extracted_obj[2], b=extracted_obj[3], theta=extracted_obj[4]) #flux /= diff_cube_test.sum() ap_data.append(flux) plt.ylim((0,800)) plt.plot(frame_data, ap_data, '-o', color=colors[i],linewidth=5.0, ) plt.show() plt.figure(2, figsize=(10, 12)) plt.imshow(diff_cube[1], cmap='gray', vmin=1, vmax=12) plt.colorbar() for i, extracted_obj in enumerate(unique_extracted_objects): positions = (extracted_obj[0], extracted_obj[1]) apertures = CircularAperture(positions, r=5.) apertures.plot(color=colors[i], linewidth=10.0, lw=2.5, alpha=0.5)
def plot_peaks(box, x_peaks, y_peaks, radius=None, title=None, vmin=None, vmax=None): """ This function plots the data with peaks marked ... :param box: :param x_peaks: :param y_peaks: :return: """ # Determine the maximum value in the box and the minium value for plotting if vmin is None: vmin = max(np.nanmin(box), 0.) if vmax is None: vmax = 0.5 * (np.nanmax(box) + vmin) # Set the normalization norm = ImageNormalize(stretch=SqrtStretch()) # Make the plot plt.figure(figsize=(8,2.5)) plt.imshow(box, origin='lower', norm=norm, interpolation='nearest', vmin=vmin, vmax=vmax, cmap="viridis") if radius is None: plt.plot(x_peaks, y_peaks, ls='none', color='white', marker='+', ms=40, lw=10, mew=4) else: positions = (x_peaks, y_peaks) apertures = CircularAperture(positions, r=radius) apertures.plot(color='green', lw=1.5, alpha=0.5) plt.xlim(0, box.shape[1]-1) plt.ylim(0, box.shape[0]-1) if title is not None: plt.title(title) plt.show()
def plot_it(big_green, small_red, fits_file, wcs, title, padding=PADDING): logging.info("plotting {} green and {} red circles.".format(len(big_green), len(small_red))) big_green = add_pixels(big_green, wcs, PADDING) small_red = add_pixels(small_red, wcs, PADDING) hdulist = fits.open(fits_file) data = hdulist[0].data.astype(float) data = np.pad(data, (padding, padding), 'constant', constant_values=(100, 100)) fig=plt.figure(figsize=(36, 32), dpi= 80, facecolor='w', edgecolor='k') big_green_positions = ([o.xpos for o in big_green],[o.ypos for o in big_green]) small_red_positions = ([o.xpos for o in small_red],[o.ypos for o in small_red]) big_green_apps = CircularAperture(big_green_positions, r=10.) small_red_apps = CircularAperture(small_red_positions, r=5.) # target_app = CircularAperture(target_xy, r=20.) plt.title('Test') plt.imshow(data, cmap='gray_r', origin='lower', vmin=0, vmax=2500) big_green_apps.plot(color='green', lw=1.5, alpha=0.5) small_red_apps.plot(color='red', lw=1.5, alpha=0.5) # target_app.plot(color='blue', lw=1.5, alpha=0.5) #to_plot = results def annotate_it(results, offset1, offset2, size=16): for to_annotate in results: plt.annotate('{}'.format(to_annotate.label), xy=(to_annotate.xpos, to_annotate.ypos), xycoords='data', xytext=(offset1, offset2), textcoords='offset points', size=size, arrowprops=dict(arrowstyle="->")) annotate_it(big_green, -10, -20, size=10) annotate_it(small_red, -10, 10, size=12) return fig
def plot(sources, data, path): positions = (sources['xcentroid'], sources['ycentroid']) apertures = CircularAperture(positions, r=4.) norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.savefig(path)
def plotStars(path, image, stars): positions = zip(stars['xcentroid'], stars['ycentroid']) apertures = CircularAperture(positions, r=12) phot_table = aperture_photometry(image, apertures) plt.clf() plt.imshow(image, cmap='gray', norm=LogNorm()) apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.savefig('%s.png' % path, dpi=300)
def plot(sources, data, path): positions = (sources['x_fit'], sources['y_fit']) # TODO(ian): Show fwhm as aperture size. apertures = CircularAperture(positions, r=4.) #norm = ImageNormalize(stretch=SqrtStretch()) plt.clf() plt.imshow(data, cmap='Greys', origin='lower') #, norm=norm) apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.savefig(path)
def plot_light_curves(diff_cube, unique_extracted_objects): # The diff_cube has to be byte swapped BEFORE being sent as parameter (diff_cube.byteswap(True).newbyteorder()), otherwise the method is not goint to work. Unique_extracted_objects only work for elliptic-shapped apertures # We get the number of frames from the cube frame_data = [i for i in range(len(diff_cube))] # Random colours array colours = [ (random.uniform(0.5, 1), random.uniform(0.5, 1), random.uniform(0.5, 1)) for i in range(len(unique_extracted_objects)) ] maxVal = 0 minVal = float("inf") plt.figure(2, figsize=(10, 12)) # Bonus: Show the image with the sources on the same colour than the plots. if len(diff_cube) == 1: plt.imshow(diff_cube[0], cmap="gray", vmin=1, vmax=12) else: plt.imshow(diff_cube[1], cmap="gray", vmin=1, vmax=12) plt.colorbar() for i, extracted_obj in enumerate(unique_extracted_objects): positions = (extracted_obj[0], extracted_obj[1]) apertures = CircularAperture(positions, r=5.0) apertures.plot(color=colours[i], linewidth=10.0, lw=2.5, alpha=0.5) # For every object we are going to calculate the aperture plt.figure(1, figsize=(20, 12)) for i, extracted_obj in enumerate(unique_extracted_objects): ap_data = [] # The standard size of each independent figure # plt.figure(i, figsize=(10, 12)) # For every frame... for frame in diff_cube: diff_cube_test = frame.copy() # The parameters passed in order are x, y, a, b and theta flux, fluxerr, flag = sep.sum_ellipse( diff_cube_test, x=extracted_obj[0], y=extracted_obj[1], a=extracted_obj[2], b=extracted_obj[3], theta=extracted_obj[4], ) ap_data.append(flux) maxVal = np.maximum(maxVal, np.max(ap_data)) minVal = np.minimum(minVal, np.min(ap_data)) # Hard-coded value!!! ALERT!!! # Plot every curve as a dotted line with the points visible plt.plot(frame_data, ap_data, "-o", color=colours[i], linewidth=5.0) plt.ylim((minVal * 1.1, maxVal * 0.9)) # Voila plt.show()
def plot_phot(star_table, data, color, alpha=1): global fig, red_giant_starid, ref_starid, red_giant_iter, ref_star_iter, rg2_starid, rg2_star_iter centroids = (star_table['xcenter'], star_table['ycenter']) source_aperture = CircularAperture(centroids, r=3) sky_aperture = CircularAperture((290, 130), r=3.) sky_table = aperture_photometry(data, sky_aperture) plt.imshow(data, cmap='gray', origin='lower', vmin=0, vmax=1500, alpha=alpha) for i in range(np.shape(centroids)[1]): if (np.float64(centroids[0][i]) - 739.5)**2 + (np.float64(centroids[1][i]) - 699.)**2 < 0.5: plt.annotate("NGC 7078 682", xy=(np.float64(star_table[i][1]) + 5., np.float64(star_table[i][2]) + 5.), color=color, alpha=alpha) red_giant_starid = int(star_table[i][0]) red_giant_iter = i elif (np.float64(centroids[0][i]) - 859.)**2 + (np.float64(centroids[1][i]) - 788.)**2 < 0.5: plt.annotate("NGC 7978 341", xy=(np.float64(star_table[i][1]) + 5., np.float64(star_table[i][2]) + 5.), color=color, alpha=alpha) ref_starid = int(star_table[i][0]) ref_star_iter = i elif (np.float64(centroids[0][i]) - 500.)**2 + (np.float64(centroids[1][i]) - 740.3)**2 < 0.5: plt.annotate("NGC 7978 1030", xy=(np.float64(star_table[i][1]) + 5., np.float64(star_table[i][2]) + 5.), color=color, alpha=alpha) rg2_starid = int(star_table[i][0]) rg2_star_iter = i else: plt.annotate(str(star_table[i][0]), xy=(np.float64(star_table[i][1]) + 5., np.float64(star_table[i][2]) + 5.), color=color, alpha=alpha) source_aperture.plot(color=color, lw=1.5, alpha=0.5) plt.annotate("SKY", xy=(np.float64(sky_table[0][1]) + 15., np.float64(sky_table[0][2]) + 15.), color="white") sky_aperture.plot(color="orange", lw=0.5, alpha=0.5) plt.tight_layout()
def find_sources(data, threshold=30, fwhm=3.0, show_sources=True, save_sources=False, plot_name='sources.png'): """Use photutils' DAOFind to locate sources in the input image. Parameters ---------- data : numpy.ndarray 2D image threshold : float Number of sigma above the background used to determine the presence of a source show_sources : bool If True, create an image with overlain marks showing sources save_sources : bool If True, save the image of the source locations at ```plot_name``` plot_name : str Name of file to save the image with marked sources Returns ------- sources : astropy.table.Table Table of source positions """ mean, median, std = sigma_clipped_stats(data, sigma=3.0) daofind = DAOStarFinder(fwhm=fwhm, threshold=threshold * std) sources = daofind(data - median) if sources is not None: print('{} sources found.'.format(len(sources))) if show_sources or save_sources: positions = np.transpose( (sources['xcentroid'], sources['ycentroid'])) apertures = CircularAperture(positions, r=4.) norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) apertures.plot(color='blue', lw=1.5, alpha=0.5) if show_sources: plt.show() if save_sources: plt.savefig(plot_name) print('Plot saved to {}'.format(plot_name)) plt.close() else: print('No sources found.') return sources
def find_sources(file_, fwhm): """ Uses DAOStarFinder to extract source positions from fits file :param file_ (str): name of target .fits file :param fwhm (float): The full width half maximum of the gaussian kernel in pixels For more config see https://photutils.readthedocs.io/en/stable/api/photutils.detection.DAOStarFinder.html """ # Read in fits file as numpy array data = read_fits(file_, return_array=True) # Calculate background level mean, median, std = stats.sigma_clipped_stats(data) print(('mean', 'median', 'std')) print((mean, median, std)) # Set up DAO Finder and run on bg subtracted image, printing results # sharplo=.2, sharphi=1., roundlo=-.3, roundhi=.3, daofind = DAOStarFinder(exclude_border=True, fwhm=fwhm, threshold=std) sources = daofind.find_stars(data - median) # daofind(data-median) # print('Sources:') print(sources) # Save positions of detected sources to csv file positions = (sources['xcentroid'], sources['ycentroid']) print_positions = zip(*[ sources[x] for x in [ 'id', 'xcentroid', 'ycentroid', 'sharpness', 'roundness1', 'roundness2', 'npix', 'sky', 'peak', 'flux', 'mag' ] ]) header = 'id,xcentroid,ycentroid,sharpness,roundness1,roundness2,npix,sky,peak,flux,mag' np.savetxt(file_[:-5] + '_positions.csv', print_positions, fmt='%.5e', header=header) # Show image with detected sources circled in blue apertures = CircularAperture(positions, r=4.) norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.draw() # Scatter plot sharpness vs magnitude plt.figure(2) sharp, round_, mags = (sources['sharpness'], sources['roundness1'], sources['mag']) plt.scatter(mags, sharp) plt.title('Sharpness vs Magnitude') plt.xlabel('Mag') plt.ylabel('Sharp') # Scatter plot roundness vs magnitude plt.figure(3) plt.scatter(mags, round_) plt.title('Roundness vs Magnitude') plt.xlabel('Mag') plt.ylabel('Roundness1') plt.show()
def ref2image(data,positions,aper,fig_name): apertures = CircularAperture(positions, r=aper[0]) annulus_apertures = CircularAnnulus(positions, r_in=aper[1], r_out=aper[2]) fig = plt.figure(figsize=(20,20));fig.add_subplot(111) apertures.plot(color='blue',lw=2,alpha=1) annulus_apertures.plot(color='red',lw=2,alpha=0.5) norm = ImageNormalize(stretch=HistEqStretch(data)) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) for i in range(len(positions)): plt.text(positions[i][0]+10,positions[i][1]+10,str(i+1),fontdict={'size':'50','color':'blue'}) plt.savefig(fig_name,dpi=150) plt.show()
def starbright(fnstar, fnflat, istar, axs, fg): # %% load data data = meanstack(fnstar, 100)[0] # %% flat field flatnorm = readflat(fnflat, fnstar) data = (data / flatnorm).round().astype(data.dtype) # %% background mean, median, std = sigma_clipped_stats(data, sigma=3.0) rfact = data.shape[0] // 40 cfact = data.shape[1] // 40 bg = Background(data, (rfact, cfact), interp_order=1, sigclip_sigma=3) # http://docs.astropy.org/en/stable/units/#module-astropy.units # dataphot = (data - bg.background)*u.ph/(1e-4*u.m**2 * u.s * u.sr) # data = (data-0.97*data.min()/bg.background.min()*bg.background) * u.ph/(u.cm**2 * u.s * u.sr) data = data * u.ph / (u.cm**2 * u.s * u.sr) # %% source extraction sources = daofind(data, fwhm=3.0, threshold=5 * std) # %% star identification and quantification XY = column_stack((sources["xcentroid"], sources["ycentroid"])) apertures = CircularAperture(XY, r=4.0) norm = ImageNormalize(stretch=SqrtStretch()) flux = apertures.do_photometry(data, effective_gain=camgain)[0] # %% plots fg.suptitle("{}".format(fnflat.parent), fontsize="x-large") hi = axs[-3].imshow(flatnorm, interpolation="none", origin="lower") fg.colorbar(hi, ax=axs[-3]) axs[-3].set_title("flatfield {}".format(fnflat.name)) hi = axs[-2].imshow(bg.background, interpolation="none", origin="lower") fg.colorbar(hi, ax=axs[-2]) axs[-2].set_title("background {}".format(fnstar.name)) hi = axs[-1].imshow(data.value, cmap="Greys", origin="lower", norm=norm, interpolation="none") fg.colorbar(hi, ax=axs[-1]) for i, xy in enumerate(XY): axs[-1].text(xy[0], xy[1], str(i), ha="center", va="center", fontsize=16, color="w") apertures.plot(ax=axs[-1], color="blue", lw=1.5, alpha=0.5) axs[-1].set_title("star {}".format(fnstar.name)) return flux[istar]
def plot_image_wsource(scidata, imstat, sigscalel, sigscaleh, sources=None, xy=None, figname=None, display=True): """""" eps = 1.0e-9 sigscalel = -np.abs(sigscalel) # Expected to be negative. sigscaleh = np.abs(sigscaleh) # Expected to be positive. matplotlib.rcParams.update({'font.size': 24}) # Adjust font. flat = scidata.flatten() vmin = np.min( flat[flat > imstat[2] + imstat[3] * sigscalel]) - imstat[0] + eps vmax = np.max( flat[flat < imstat[2] + imstat[3] * sigscaleh]) - imstat[0] + eps if sources is not None: positions = np.column_stack( [sources['xcentroid'], sources['ycentroid']]) elif xy is not None: positions = np.column_stack(xy) else: raise ValueError('Either sources or xy must be give.') apertures = CircularAperture(positions, r=4.) plt.figure(figsize=(20, 20)) # Adjust size of figure. imgplot = plt.imshow(scidata - imstat[0], norm=LogNorm(), vmin=vmin, vmax=vmax) # TODO scidata index? apertures.plot(color='red', lw=1.5, alpha=0.5) for i in range(len(positions)): plt.annotate('{}'.format(i), positions[i]) plt.axis((-0.5, scidata.shape[1] - 0.5, -0.5, scidata.shape[0] - 0.5)) plt.xlabel("Column (Pixels)") plt.ylabel("Row (Pixels)") if figname is not None: plt.savefig(figname) if display: plt.show() plt.close() return
def __init__(self, hdu, plot=True, num_std=20, max_stars=300, query_radius=5.): ''' :param hdu: :param plot: :param num_std: :param max_stars: :param query_radius: ''' self.data = hdu.data.copy() self.header = hdu.header.copy() # Extract star positions and magnitudes from image mean, med, std = sigma_clipped_stats(self.data) daofind = DAOStarFinder(fwhm=3, threshold=num_std * std) sources = daofind(self.data - med) self.pixel_positions = (sources['xcentroid'], sources['ycentroid']) self.inst_magnitudes = sources['mag'] if (plot): apertures = CircularAperture(self.pixel_positions, r=4) norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(self.data, cmap='Greys', origin='lower', norm=norm) apertures.plot(color='blue', lw=1.5, alpha=0.5) self.wcs_orig = wcs.WCS(self.header) (self.ra_orig, self.dec_orig) = self.wcs_orig.all_pix2world(self.pixel_positions[0], self.pixel_positions[1], 0) arr_ref = query_vizier(query_radius, self.header['CRVAL1'], self.header['CRVAL2'], max_stars=max_stars) self.ra_ref = arr_ref[:, 0] self.dec_ref = arr_ref[:, 1] self.mag_ref = arr_ref[:, 2] (self.xpix_ref, self.ypix_ref) = self.wcs_orig.all_world2pix(self.ra_ref, self.dec_ref, 0) (self.xpix_orig, self.ypix_orig) = self.pixel_positions if (plot): ref_aper = CircularAperture((self.xpix_ref, self.ypix_ref), r=4) ref_aper.plot(color='red', lw=1.5, alpha=0.5) plt.show()
def imageshow(data,positions,aper=[8,12,20],rim_size=50): min_x=int(np.min(positions.T[0]))-rim_size;max_x=int(np.max(positions.T[0]))+rim_size min_y=int(np.min(positions.T[1]))-rim_size;max_y=int(np.max(positions.T[1]))+rim_size data=data[min_y:max_y,min_x:max_x] positions=positions-np.array([min_x,min_y]) apertures = CircularAperture(positions, r=aper[0]) annulus_apertures = CircularAnnulus(positions, r_in=aper[1], r_out=aper[2]) fig = plt.figure(figsize=(20,20));fig.add_subplot(111) apertures.plot(color='blue',lw=2,alpha=1) annulus_apertures.plot(color='red',lw=2,alpha=0.5) norm = ImageNormalize(stretch=HistEqStretch(data)) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) plt.show()
def display_image(img, minclip=5, maxclip=95, label=None, cmap='Greys_r', srcs=None, projection=None, calibrated=False, png=None): """Simple wrapper to display an image. """ from astropy.visualization import AsinhStretch as Stretch from astropy.visualization import ZScaleInterval as Interval from astropy.visualization.mpl_normalize import ImageNormalize #from astropy.visualization import simple_norm #norm = simple_norm(img, min_percent=minclip, max_percent=maxclip) interval = Interval(contrast=0.5) vmin, vmax = interval.get_limits(img) norm = ImageNormalize(interval=interval, stretch=Stretch(a=0.9)) fig, ax = plt.subplots(figsize=(8, 8), subplot_kw={'projection': projection}) im = ax.imshow(img, origin='lower', norm=norm, cmap=cmap, vmin=vmin, vmax=vmax) if projection: ax.coords.grid(color='red') ax.coords['ra'].set_axislabel('Right Ascension') ax.coords['dec'].set_axislabel('Declination') else: ax.set_xlabel('Column Number (pixels)') ax.set_ylabel('Row Number (pixels)') # Mark the locations of stars. if srcs: from photutils import CircularAperture pos = np.transpose((srcs['xcentroid'], srcs['ycentroid'])) aps = CircularAperture(pos, r=12.) aps.plot(color='red', lw=1.5, alpha=0.6, axes=ax) # Make room for the colorbar fig.subplots_adjust(right=0.8) cax = fig.add_axes([0.85, 0.28, 0.05, 0.45]) c = plt.colorbar(im, cax=cax) if label: c.set_label(label) else: if calibrated: c.set_label(r'Intensity ($e^{-}/s$)') else: c.set_label('Intensity (ADU)') if png: print('Writing {}'.format(png)) fig.savefig(png)
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 diagnostic_source_finding_plots(ifile, coo_tab=None): hdu = fits.open(ifile) data = hdu[0].data norm = ImageNormalize(stretch=LogStretch()) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) if coo_tab: positions = (np.array(coo_tab['xcentroid'].tolist()), \ np.array(coo_tab['ycentroid'].tolist())) apertures = CircularAperture(positions, r=10.) apertures.plot(color='blue', lw=2, alpha=1) plt.show()
def show_sources(image, sources, num_stars=10): ''' similar to `show_peaks`; difference is `sources` used as input ''' positions = (sources['xcentroid'].values[:num_stars], sources['ycentroid'].values[:num_stars]) apertures = CircularAperture(positions, r=20.) vmin, vmax = ZScaleInterval().get_limits(image) plt.figure(figsize=(10, 10)) plt.imshow(image, origin='lower', vmin=vmin, vmax=vmax) for num, (x, y) in enumerate(zip(positions[0], positions[1])): plt.text(x + 5, y + 5, num + 1, fontsize=20, color='w') apertures.plot(color='r', lw=2) #return None plt.show()
def showDetection(self, pos): data = self.get8BitFitsData(pos) # Create image from data array image = Image.fromarray(data, 'L') image = image.transpose(Image.FLIP_TOP_BOTTOM) sources = self.__starsDetection[pos] positions = (sources['xcentroid'], sources['ycentroid']) apertures = CircularAperture(positions, r=5.) norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(image, cmap='Greys', origin='lower') apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.show()
def get_apertures(sources): logging.info('Creating apertures') positions_real = np.transpose( (sources['real_xcentroid'], sources['real_ycentroid'])) positions_ghost = np.transpose( (sources['ghost_xcentroid'], sources['ghost_ycentroid'])) for number, (pos_real, pos_ghost) in enumerate(zip(positions_real, positions_ghost)): apertures = CircularAperture([pos_real, pos_ghost], r=4) plt.text(pos_ghost[0] + 5, pos_ghost[1] + 5, number) plt.text(pos_real[0] + 5, pos_real[1] + 5, number) apertures.plot(color=np.random.rand(3, )) logging.info('Plotting apertures for %s stars', str(len(sources))) logging.info('Finished') return apertures
def show_image(self,sourceRA,sourceDEC,refRA,refDEC): print('RED circle is the cepheid. WHITE circle is the reference object(s).') print('Add more reference stars by defining ref1aper = blahblahbelow, and ref1aper.plot(etc...)') #aper_annulus = CircularAnnulus((sourceRA, sourceDEC), r_in=6., r_out = 8.) apertures = CircularAperture((self.worldcoord.wcs_world2pix(sourceRA,sourceDEC,0)), r=6) ref1aper = CircularAperture((self.worldcoord.wcs_world2pix(refRA,refDEC,0)), r=6) #ref2aper = CircularAperture((worldcoord.wcs_world2pix(ref2RA,ref2DEC,0)), r=7) #ref3aper = CircularAperture((worldcoord.wcs_world2pix(ref3RA,ref3DEC,0)), r=3.5) #darkaper = CircularAperture((worldcoord.wcs_world2pix(darkRA,darkDEC,0)), r=3.5) fig = plt.figure() fig.add_subplot(111, projection = self.worldcoord) plt.imshow(self.stardata,origin='lower', cmap='Spectral') apertures.plot(color='red',lw=1.5, alpha=0.5) ref1aper.plot(color='white', lw=2.5, alpha=0.5)
def processImage(path, index=0): fp = pyfits.open(path) hdu = fp[index] image = hdu.data.astype('float32') image -= np.median(image) stars = findStars(image) # positions = zip(stars['xcentroid'], stars['ycentroid']) apertures = CircularAperture(positions, r=12) phot_table = aperture_photometry(image, apertures) #print phot_table # plt.clf() image = hdu.data.astype('float32') plt.imshow(image, cmap='gray', norm=LogNorm()) apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.savefig('%s.png' % path, dpi=300)
def photometry(self, instrument, save=True): pixx, pixy = self.xy aprad = self.pad['aprad'] aperture = CircularAperture((pixx, pixy), r=aprad) tmp = fits.open(self.subfile) tmpdata = tmp[1].data exptime = tmp[0].header['EXPTIME'] dateobs = tmp[0].header['DATE-OBS'] filt = tmp[0].header['FILTER'] error = calc_total_error(tmpdata, bkg_error=np.zeros_like(tmpdata), effective_gain=exptime) phot_table = aperture_photometry(tmpdata, aperture, error=error) photapcorr = PhotApCorr() wave, zp = photapcorr.table[instrument]['ZP'][filt] scale = photapcorr.table[instrument]['scale'] apsize = aprad * scale apcorr = photapcorr.table[instrument]['model'](wave, apsize)[0] mag = -2.5 * np.log10(phot_table['aperture_sum'] / apcorr) + zp emag = 2.5 * np.sqrt(phot_table['aperture_sum_err']** 2) / (phot_table['aperture_sum'] * np.log(10.)) tmp = { 'phot_table': phot_table, 'apcorr': apcorr, 'mag': (mag[0], emag[0]), 'wavelength': wave, 'zp': zp } self.phot_table = tmp ########## ########## ########## plt.figure() plt.imshow(tmpdata, origin='lower', cmap='viridis', vmin=-1, vmax=1) aperture.plot(color='red') dx, dy = 3, 3 plt.xlim(pixx - aprad - dx, pixx + aprad + dx) plt.ylim(pixy - aprad - dy, pixy + aprad + dy) string = '{0}\n{1}\n{2}\n{3:.3f} +/- {4:.3f} mag'.format( self.root, dateobs, filt, mag[0], emag[0]) plt.title(string, fontsize=14) plt.tight_layout() if save: string = '{0}_photometry.eps'.format(self.root) plt.savefig(string, format='eps', bbox_inches='tight') print('Save to {0}'.format(string))
def starbright(fnstar,fnflat,istar,axs,fg): #%% load data data = meanstack(fnstar,100)[0] #%% flat field flatnorm = readflat(fnflat,fnstar) data = (data/flatnorm).round().astype(data.dtype) #%% background mean, median, std = sigma_clipped_stats(data, sigma=3.0) rfact=data.shape[0]//40 cfact=data.shape[1]//40 bg = Background(data,(rfact,cfact),interp_order=1, sigclip_sigma=3) # http://docs.astropy.org/en/stable/units/#module-astropy.units #dataphot = (data - bg.background)*u.ph/(1e-4*u.m**2 * u.s * u.sr) # data = (data-0.97*data.min()/bg.background.min()*bg.background) * u.ph/(u.cm**2 * u.s * u.sr) data = data* u.ph/(u.cm**2 * u.s * u.sr) #%% source extraction sources = daofind(data, fwhm=3.0, threshold=5*std) #%% star identification and quantification XY = column_stack((sources['xcentroid'], sources['ycentroid'])) apertures = CircularAperture(XY, r=4.) norm = ImageNormalize(stretch=SqrtStretch()) flux = apertures.do_photometry(data,effective_gain=camgain)[0] #%% plots fg.suptitle('{}'.format(fnflat.parent),fontsize='x-large') hi = axs[-3].imshow(flatnorm,interpolation='none',origin='lower') fg.colorbar(hi,ax=axs[-3]) axs[-3].set_title('flatfield {}'.format(fnflat.name)) hi = axs[-2].imshow(bg.background,interpolation='none',origin='lower') fg.colorbar(hi,ax=axs[-2]) axs[-2].set_title('background {}'.format(fnstar.name)) hi = axs[-1].imshow(data.value, cmap='Greys', origin='lower', norm=norm,interpolation='none') fg.colorbar(hi,ax=axs[-1]) for i,xy in enumerate(XY): axs[-1].text(xy[0],xy[1], str(i),ha='center',va='center',fontsize=16,color='w') apertures.plot(ax=axs[-1], color='blue', lw=1.5, alpha=0.5) axs[-1].set_title('star {}'.format(fnstar.name)) return flux[istar]
def aper_phot(img_data,positions, r = 10., r_in = 14., r_out = 18,bkg_sub=False,plot=False): """ :params: r: Aperture Radius :params: r_in: annulus aperture inside radius :params: r_out: annulus aperture outside radius :params: bkg_sub: True if background subtraction is needed :params: plot: True to plot :out: phot_table: Table with the values of the aperture photometry """ #Background subtraction if bkg_sub == True: sigma_clip = SigmaClip(sigma=3., iters=10) bkg_estimator = MedianBackground() bkg = Background2D(img_data, (50, 50), filter_size=(3, 3),sigma_clip=sigma_clip, bkg_estimator=bkg_estimator) data_sub = img_data - bkg.background else: data_sub = img_data #Aperture Photometry using a circular aperture and a circular annulus apertures = CircularAperture(positions, r=r) annulus_apertures = CircularAnnulus(positions,r_in = r_in,r_out = r_out) apers = [apertures,annulus_apertures] phot_table = aperture_photometry(data_sub, apers) bkg_mean = phot_table['aperture_sum_1'] / annulus_apertures.area() bkg_sum = bkg_mean * apertures.area() final_sum = phot_table['aperture_sum_0'] - bkg_sum phot_table['residual_aperture_sum'] = final_sum positions = np.array(positions) if plot == True: #Ploting norm = ImageNormalize(data_sub, interval=ZScaleInterval(),stretch=LinearStretch()) plt.imshow(data_sub, cmap='Greys', origin='lower',norm=norm) apertures.plot(color='blue', lw=1.5, alpha=0.5) annulus_apertures.plot(color='green',lw=1.5,alpha=0.5) plt.plot(positions[:,0],positions[:,1], ls='none', color = 'red', marker='.', ms=10, lw=1.5) plt.xlim(0, data_sub.shape[1]-1) plt.ylim(0, data_sub.shape[0]-1) plt.show() return phot_table
def process_file(inpath, file_name, t_constant, sigma, fwhm, r, kernel_size, outpath, plot): print "Processing " + file_name hdulist = fits.open(inpath + file_name) image = hdulist[0].data if isinstance(sigma, list): threshold = calc_sigma(image, sigma[0], sigma[1]) * t_constant else: threshold = t_constant*sigma median_out = signal.medfilt(image,kernel_size) median_sub = np.subtract(image,median_out) sources = daofind(median_sub, threshold, fwhm) sources_2 = np.array(sources["id", "xcentroid", "ycentroid", "sharpness", "roundness1", "roundness2", "npix", "sky", "peak", "flux", "mag"]) print_line= (file_name+","+str(sources_2)) base_name = os.path.splitext(file_name)[0] file = open(outpath + base_name + ".out", "a") file.write(print_line) file.close() positions = (sources['xcentroid'], sources['ycentroid']) # print positions apertures = CircularAperture(positions, r) phot_table = aperture_photometry(median_sub, apertures) phot_table_2 = np.array(phot_table["aperture_sum", "xcenter", "ycenter"]) print_line= (","+str(phot_table_2)+"\n") file = open(outpath + base_name + ".out", "a") file.write(print_line) file.write("\n") file.close() hdulist[0].data = median_sub file = open(outpath + base_name + ".fits", "w") hdulist.writeto(file) file.close() if plot: median_sub[median_sub<=0]=0.0001 plt.imshow(median_sub, cmap='gray', origin='lower') apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.show()
def find_stars(image, plot = False, fwhm = 20.0, threshold=3.): from astropy.stats import sigma_clipped_stats mean, median, std = sigma_clipped_stats(image, sigma=3.0) from photutils import daofind sources = daofind(image - median, fwhm=fwhm, threshold=threshold*std) # stars already found accurately, vet_sources will be implemented when working properly # vet_sources(10.0,10.0) if plot == True: # from astropy.visualization import SqrtStretch # from astropy.visualization.mpl_normalize import ImageNormalize positions = (sources['xcentroid'], sources['ycentroid']) apertures = CircularAperture(positions, r=4.) #norm = ImageNormalize(stretch=SqrtStretch()) #plt.imshow(image, cmap='Greys', origin='lower', norm=norm) qi.display_image(image) apertures.plot(color='blue', lw=1.5, alpha=0.5) return sources
def plot(self,scale='log'): apertures = CircularAperture([self.locx,self.locy], r=self.r) z = self.copy() z -= np.nanmedian(z) if scale=='log': z = np.log10(self) z = ma.masked_invalid(z) z.mask = z.mask | (z < 0) z.fill_value = 0 z = z.filled() imshow2(z) if self.pixels is not None: for i,pos in enumerate(self.pixels): r,c = pos plt.text(c,r,i,va='center',ha='center',color='Orange') apertures.plot(color='Lime',lw=1.5,alpha=0.5) plt.xlabel('Column (pixels)') plt.ylabel('Row (pixels)')
def try_dao(fitsfile, outfile='out.png'): hdulist = fits.open(fitsfile) hdu = hdulist[0] if len(hdu.data.shape) == 3: data = hdu.data[0] else: data = hdu.data mean, median, std = sigma_clipped_stats(data[800:900, 800:900], sigma=3.0, iters=5) print(mean, median, std) #data = hdu.data sources = daofind(data - median, fwhm=3.0, threshold=5.*std) print 'Found %i sources' % len(sources) positions = (sources['xcentroid'], sources['ycentroid']) apertures = CircularAperture(positions, r=4.) norm = ImageNormalize(stretch=SqrtStretch(), vmin=2000, vmax=3000) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) plt.title('%i Sources from a single all-sky frame' % len(sources)) apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.savefig(filename=outfile)
def init_centroids(first_image_path, master_flat, master_dark, target_centroid, max_number_stars=10, min_flux=0.2, plots=False): first_image = np.median([(fits.getdata(path) - master_dark)/master_flat for path in first_image_path], axis=0) tophat_kernel = Tophat2DKernel(5) convolution = convolve_fft(first_image, tophat_kernel, fftn=fft2, ifftn=ifft2) convolution -= np.median(convolution) mad = mad_std(convolution) convolution[convolution < -5*mad] = 0.0 from skimage.filters import threshold_yen from skimage.measure import label, regionprops thresh = threshold_yen(convolution)/4 # Use /4 for planet c, /2 for planet b #thresh = threshold_otsu(convolution)/15 masked = np.ones_like(convolution) masked[convolution <= thresh] = 0 label_image = label(masked) plt.figure() plt.imshow(label_image, origin='lower', cmap=plt.cm.viridis) plt.show() # regions = regionprops(label_image, convolution) regions = regionprops(label_image, first_image) # reject regions near to edge of detector buffer_pixels = 50 regions = [region for region in regions if ((region.weighted_centroid[0] > buffer_pixels and region.weighted_centroid[0] < label_image.shape[0] - buffer_pixels) and (region.weighted_centroid[1] > buffer_pixels and region.weighted_centroid[1] < label_image.shape[1] - buffer_pixels))] #centroids = [region.weighted_centroid for region in regions] #intensities = [region.mean_intensity for region in regions] target_intensity = regions[0].mean_intensity target_diameter = regions[0].equivalent_diameter # and region.equivalent_diameter > 0.8 * target_diameter centroids = [region.weighted_centroid for region in regions if min_flux * target_intensity < region.mean_intensity] # intensities = [region.mean_intensity for region in regions # if min_flux * target_intensity < region.mean_intensity] # centroids = np.array(centroids)[np.argsort(intensities)[::-1]] distances = [np.sqrt((target_centroid[0] - d[0])**2 + (target_centroid[1] - d[1])**2) for d in centroids] centroids = np.array(centroids)[np.argsort(distances)] positions = np.vstack([[y for x, y in centroids], [x for x, y in centroids]]) if plots: apertures = CircularAperture(positions, r=12.) apertures.plot(color='r', lw=2, alpha=1) plt.imshow(first_image, vmin=np.percentile(first_image, 0.01), vmax=np.percentile(first_image, 99.9), cmap=plt.cm.viridis, origin='lower') plt.scatter(positions[0, 0], positions[1, 0], s=150, marker='x') plt.show() return positions
tp.lightcurve(info) position = (xnew,ynew) aperture = CircularAperture(position, r=radius) bkg_aperture = CircularAnnulus(position, r_in=15., r_out=20.) # perform the photometry; the default method is 'exact' phot = aperture_photometry(image, aperture) bkg = aperture_photometry(image, bkg_aperture) # calculate the mean background level (per pixel) in the annuli bkg_mean = bkg['aperture_sum'] / bkg_aperture.area() bkg_mean bkg_sum = bkg_mean * aperture.area() # plot the apertures plt.imshow(scale_image(image, scale='sqrt', percent=98.), origin='lower',cmap='gray') aperture.plot(color='blue') bkg_aperture.plot(color='cyan', hatch='//', alpha=0.8) plt.xlim(xnew-100,xnew+100) plt.ylim(ynew-100,ynew+100) phot['bkg_sum'] = bkg_sum
def fors2_pol_phot(folder_path,apermul): """ Script runs photometry for FORS2 polarimetry images """ # Read in four wave plate angle files and set up arrays for later file_ang0 = os.path.join(folder_path,'0ang.fits') file_ang225 = os.path.join(folder_path,'225ang.fits') file_ang45 = os.path.join(folder_path,'45ang.fits') file_ang675 = os.path.join(folder_path,'675ang.fits') files = [file_ang0,file_ang225,file_ang45,file_ang675] angle = ['0','225','45','675'] ang_dec = ['0','22.5','45','67.5'] label = ['$0^{\circ}$ image','$22.5^{\circ}$ image', '$45^{\circ}$ image','$67.5^{\circ}$ image'] # Set up array to store FWHM and number of sources per half-wave plate fwhm = [] numsource = [] # Loop over files for the four wave plate files for k in range(0,len(angle),1): # Open fits file, extract pixel flux data and remove saturated pixels try: hdulist = fits.open(files[k]) image_data = hdulist[0].data except FileNotFoundError as e: print("Cannot find the fits file(s) you are looking for!") print("Please check the input!") sys.exit() # Remove bad pixels and mask edges image_data[image_data > 60000] = 0 image_data[image_data < 0] = 0 rows = len(image_data[:,0]) cols = len(image_data[0,:]) hdulist.close() # Calculate estimate of background using sigma-clipping and detect # the sources using DAOStarFinder xord, yord = 843, 164 xexord, yexord = 843, 72 go_bmean, go_bmedian, go_bstd = sigma_clipped_stats(image_data [yord-40:yord+40,xord-40:xord+40],sigma=3.0,iters=5) ge_bmean, ge_bmedian, ge_bstd = sigma_clipped_stats(image_data [yexord-40:yexord+40,xord-40:xord+40],sigma=3.0,iters=5) daofind_o = DAOStarFinder(fwhm=5,threshold=5*go_bstd, exclude_border=True) daofind_e = DAOStarFinder(fwhm=5,threshold=5*ge_bstd, exclude_border=True) sources_o = daofind_o(image_data[yord-20:yord+20,xord-20:xord+20]) sources_e = daofind_e(image_data[yexord-20:yexord+20,xexord-20: xexord+20]) if (len(sources_o) < 1 or len(sources_e) < 1): print("No source detected in",ang_dec[k],"degree image") sys.exit() if len(sources_o) != len(sources_e): print("Unequal number of sources detected in o and e images!") sys.exit() glob_bgm = [go_bmean,ge_bmean] glob_bgerr = [go_bstd,ge_bstd] # Convert the source centroids back into detector pixels sources_o['xcentroid'] = sources_o['xcentroid'] + xord - 20 sources_o['ycentroid'] = sources_o['ycentroid'] + yord - 20 sources_e['xcentroid'] = sources_e['xcentroid'] + xexord - 20 sources_e['ycentroid'] = sources_e['ycentroid'] + yexord - 20 # Estimate the FWHM of the source by simulating a 2D Gaussian # (only done on 0 angle image ensuring aperture sizes are equal) if not fwhm: xpeaks_o = [] xpeaks_e = [] ypeaks_o = [] ypeaks_e = [] for i in range(0,len(sources_o),1): data_o = image_data[yord-20:yord+20,xord-20:xord+20] xpeaks_o.append(int(sources_o[i]['xcentroid']) - (xord - 20)) ypeaks_o.append(int(sources_o[i]['ycentroid']) - (yord - 20)) data_e = image_data[yexord-20:yexord+20,xexord-20:xexord+20] xpeaks_e.append(int(sources_e[i]['xcentroid']) - (xexord - 20)) ypeaks_e.append(int(sources_e[i]['ycentroid']) - (yexord - 20)) min_count_o = np.min(data_o) min_count_e = np.min(data_e) max_count_o = data_o[ypeaks_o[i],xpeaks_e[i]] max_count_e = data_e[ypeaks_o[i],xpeaks_e[i]] half_max_o = (max_count_o + min_count_o)/2 half_max_e = (max_count_e + min_count_e)/2 # Crude calculation for each source nearest_above_x_o = ((np.abs(data_o[ypeaks_o[i], xpeaks_o[i]:-1] - half_max_o)).argmin()) nearest_below_x_o = ((np.abs(data_o[ypeaks_o[i],0: xpeaks_o[i]] - half_max_o)).argmin()) nearest_above_x_e = ((np.abs(data_e[ypeaks_e[i], xpeaks_e[i]:-1] - half_max_e)).argmin()) nearest_below_x_e = ((np.abs(data_e[ypeaks_e[i],0: xpeaks_e[i]] - half_max_e)).argmin()) nearest_above_y_o = ((np.abs(data_o[ypeaks_o[i]:-1, xpeaks_o[i]] - half_max_o)).argmin()) nearest_below_y_o = ((np.abs(data_o[0:ypeaks_o[i], xpeaks_o[i]] - half_max_o)).argmin()) nearest_above_y_e = ((np.abs(data_e[ypeaks_e[i]:-1, xpeaks_e[i]] - half_max_e)).argmin()) nearest_below_y_e = ((np.abs(data_e[0:ypeaks_e[i], xpeaks_e[i]] - half_max_e)).argmin()) fwhm.append((nearest_above_x_o + (xpeaks_o[i] - nearest_below_x_o))) fwhm.append((nearest_above_y_o + (ypeaks_o[i] - nearest_below_y_o))) fwhm.append((nearest_above_x_e + (xpeaks_e[i] - nearest_below_x_e))) fwhm.append((nearest_above_y_e + (ypeaks_e[i] - nearest_below_y_e))) fwhm = np.mean(fwhm) # Stack both ord and exord sources together tot_sources = vstack([sources_o,sources_e]) # Store the ordinary and extraordinary beam source images and # create apertures for aperture photometry positions = np.swapaxes(np.array((tot_sources['xcentroid'], tot_sources['ycentroid']),dtype='float'),0,1) aperture = CircularAperture(positions, r=0.5*apermul*fwhm) phot_table = aperture_photometry(image_data,aperture) # Set up arrays of ord and exord source parameters s_id = np.zeros([len(np.array(phot_table['id']))]) xp = np.zeros([len(s_id)]) yp = np.zeros([len(s_id)]) fluxbgs = np.zeros([len(s_id)]) mean_bg = np.zeros([len(s_id)]) bg_err = np.zeros([len(s_id)]) s_area = [] ann_area = [] for i in range(0,len(np.array(phot_table['id'])),1): s_id[i] = np.array(phot_table['id'][i]) xpos = np.array(phot_table['xcenter'][i]) ypos = np.array(phot_table['ycenter'][i]) xp[i] = xpos yp[i] = ypos s_area.append(np.pi*(0.5*apermul*fwhm)**2) j = i%2 fluxbgs[i] = (phot_table['aperture_sum'][i] - aperture.area()*glob_bgm[j]) mean_bg[i] = glob_bgm[j] bg_err[i] = glob_bgerr[j] ann_area.append(80*80) # Create and save the image in z scale and overplot the ordinary and # extraordinary apertures and local background annuli if applicable fig = plt.figure() zscale = ZScaleInterval(image_data) norm = ImageNormalize(stretch=SqrtStretch(),interval=zscale) image = plt.imshow(image_data,cmap='gray',origin='lower',norm=norm) bg_annulus_o = RectangularAnnulus((843,159),w_in=0,w_out=80,h_out=80, theta=0) bg_annulus_e = RectangularAnnulus((843,69),w_in=0,w_out=80,h_out=80, theta=0) bg_annulus_o.plot(color='skyblue',lw=1.5,alpha=0.5) bg_annulus_e.plot(color='lightgreen',lw=1.5,alpha=0.5) for i in range(0,len(np.array(phot_table['id'])),1): aperture = CircularAperture((xp[i],yp[i]),r=0.5*apermul*fwhm) if i < int(len(np.array(phot_table['id']))/2): aperture.plot(color='blue',lw=1.5,alpha=0.5) else: aperture.plot(color='green',lw=1.5,alpha=0.5) plt.xlim(760,920) plt.ylim(20,210) plt.title(label[k]) image_fn = folder_path + angle[k] + '_image.png' fig.savefig(image_fn) # Write ordinary and extraordinary beams to file following the # convention angleXXX_ord.txt and angleXXX_exord.txt orig_stdout = sys.stdout ord_result_file= folder_path + 'angle' + angle[k] + '_ord.txt' ordresultf = open(ord_result_file, 'w') sys.stdout = ordresultf print("# id, xpix, ypix, fluxbgs, sourcearea, meanbg, bgerr, bgarea") for i in range(0,int(len(np.array(phot_table['id']))/2),1): print(i+1,xp[i],yp[i],fluxbgs[i],s_area[i],mean_bg[i],bg_err[i], ann_area[i]) sys.stdout = orig_stdout ordresultf.close() orig_stdout = sys.stdout exord_result_file = folder_path + 'angle' + angle[k] + '_exord.txt' exordresultf = open(exord_result_file, 'w') sys.stdout = exordresultf print("# id, xpix, ypix, fluxbgs, sourcearea, meanbg, bgerr, bgarea") for i in range(int(len(np.array(phot_table['id']))/2),len(np.array (phot_table['id'])),1): print(i+1-int(len(np.array(phot_table['id']))/2),xp[i],yp[i], fluxbgs[i],s_area[i],mean_bg[i],bg_err[i],ann_area[i]) sys.stdout = orig_stdout exordresultf.close() # Save the number of sources in each beam to a list numsource.append(int(len(np.array(phot_table['id']))/2)) # Print number of sources per half-wave plate image for i in range(0,len(numsource),1): print("No of sources detected at",ang_dec[i],"degrees:",numsource[i]) return 0
def extension(self, extension_idx, threshold='', FWHM=3.0, sigma=3.0, snr=50., plot=False): ''' A method to run aperatue photometry routines on an individual extension and save the results to the exposure class Parameters ---------- extension_idx: int Index of the extension threshold: float (optional) The absolute image value above which to select sources FWHM: float The full width at half maximum sigma: float Number of standard deviations to use for background estimation snr: float The signal-to-noise ratio to use in the threshold detection plot: bool Plot the field with identified sources circled Returns ------- source_list: table A source list for the image ''' # Define the data array data = self.hdulist[extension_idx].data.astype(np.float) # Extract the header and create a WCS object hdr = self.hdulist[extension_idx].header wcs = WCS(hdr) # Estimate the background and background noise mean, median, std = sigma_clipped_stats(data, sigma=sigma, iters=5) # Calculate the detection threshold and FWHM if not provided if not threshold: threshold = np.mean(detect_threshold(data, snr=snr)) # Print the parameters being used for p,v in zip(['mean','median','std','threshold','FWHM'],[mean,median,std,threshold,FWHM]): print '{!s:10}: {:.3f}'.format(p,v) # Subtract background and generate sources list of all detections sources = daofind(data-median, threshold, FWHM) # Map RA and Dec to pixels positions = (sources['xcentroid'], sources['ycentroid']) skycoords = pixel_to_skycoord(*positions, wcs=wcs) # Calculate magnitudes at given source positions apertures = CircularAperture(positions, r=2.) photometry_table = aperture_photometry(data, apertures) # 'skycoords' IRCS object is problematic for stacking tables so for now we'll just add the ra and dec # photometry_table['sky_center'] = skycoords photometry_table['ra'], photometry_table['dec'] = skycoords.ra, skycoords.dec # Update data in the exposure object self.source_table = vstack([self.source_table,photometry_table], join_type='inner') # Plot the sources if plot: norm = ImageNormalize(stretch=SqrtStretch()) plt.imshow(data, cmap='Greys', origin='lower', norm=norm) apertures.plot(color='blue', lw=1.5, alpha=0.5) print '{!s:10}: {}'.format('sources',len(sources))
groups = daogroup(intab, crit_separation=2.0*sigma_psf*gaussian_sigma_to_fwhm) plt.subplot(1, 2, 1) plt.imshow(image, origin='lower', interpolation='nearest') plt.title('Simulated data') plt.xlabel('x-position (pixel units)') plt.ylabel('y-position (pixel units)') plt.subplot(1, 2, 2) for i in range(len(groups)): for j in range(len(groups[i]['id'])): # show ids # plt.text(groups[i]['x_0'][j], groups[i]['y_0'][j], # str(groups[i]['id'][j])) aperture = CircularAperture((groups[i]['x_0'][j], groups[i]['y_0'][j]), r=sigma_psf*gaussian_sigma_to_fwhm) aperture.plot(lw=1.5, alpha=0.5) tab, residual_image = nstar(image-bkg, groups, (5,5), fitting.LevMarLSQFitter(), IntegratedGaussianPRF, sigma=2.0) tab.sort('id') tab.write('starlist_estimated.html') plt.imshow(residual_image, origin='lower', interpolation='nearest') plt.title('Residual') plt.xlabel('x-position (pixel units)') plt.ylabel('y-position (pixel units)') plt.show()
hdulist = fits.open(inpath+file_name) image = hdulist[0].data #image = image.astype(float) - np.median(image) from photutils import daofind from astropy.stats import mad_std bkg_sigma = mad_std(image) sources = daofind(image, fwhm, threshold*bkg_sigma) #print_line= (file_name+","+str(sources_2)+"\n") sources_2 = np.array(sources["id", "xcentroid", "ycentroid", "sharpness", "roundness1", "roundness2", "npix", "sky", "peak", "flux", "mag"]) print_line= (file_name+","+str(sources_2)) file= open(outpath, "a") file.write(print_line) file.close() from photutils import aperture_photometry, CircularAperture positions = (sources['xcentroid'], sources['ycentroid']) apertures = CircularAperture(positions, r) phot_table = aperture_photometry(image, apertures) phot_table_2 = np.array(phot_table["aperture_sum", "xcenter", "ycenter"]) print_line= (","+str(phot_table_2)+"\n") file= open(outpath, "a") file.write(print_line) file.close() import matplotlib.pylab as plt im2 = image im2[im2<=0]=0.0001 plt.imshow(im2, cmap='gray', origin='lower') apertures.plot(color='blue', lw=1.5, alpha=0.5) plt.show()