Beispiel #1
0
def measure_aper_flux(hdu, aper):

    # create mask (set True for where you want to mask)
    im_mask = im == 0

    # define circular aperture and annulus aperture for background subtraction
    aper = SkyCircularAperture(coords, r=radius)
    aper_annulus = SkyCircularAnnulus(coords, annulus[0], annulus[1])

    mask = aper_annulus.to_pixel(w).to_mask(method="center").data
    annulus_data = aper_annulus.to_pixel(w).to_mask(
        method="center").multiply(im)
    annulus_data_1d = annulus_data[mask > 0]
    annulus_mask = aper_annulus.to_pixel(w).to_mask(
        method="center").multiply(im_mask)
    annulus_mask_1d = annulus_mask[mask > 0]

    # determine fractional fiber coverage
    apcor_im = aper.to_pixel(w).to_mask(
        method="center").multiply(im_mask) / aper.to_pixel(w).to_mask(
            method="center").multiply(np.ones_like(im))
    apcor = np.sum(apcor_im == 0) / np.sum(np.isfinite(apcor_im))

    # get median and standard deviation in background
    mean_sigclip, median_sigclip, stddev_sigclip = sigma_clipped_stats(
        annulus_data_1d, mask=annulus_mask_1d)
    bkg_median = median_sigclip * aper.to_pixel(w).area * apcor
    bkg_stddev = stddev_sigclip * aper.to_pixel(w).area * apcor

    phottable = aperture_photometry(
        hdu[0].data,
        [aper, aper_annulus],
        error=hdu[1].data,
        mask=im_mask,
        wcs=wcs.WCS(hdu[0].header),
    )
    if np.abs(bkg_median) > 2 * bkg_stddev:
        flux = (phottable["aperture_sum_0"][0] -
                bkg_median) * u.Unit("10^-17 erg cm-2 s-1")
    else:
        flux = (phottable["aperture_sum_0"][0]) * u.Unit("10^-17 erg cm-2 s-1")

    flux_err = phottable["aperture_sum_err_0"][0] * u.Unit(
        "10^-17 erg cm-2 s-1")

    if plot:
        plt.subplot(111, projection=w)
        plt.imshow(im, vmin=0 * stddev_sigclip, vmax=3 * stddev_sigclip)
        aper.to_pixel(w).plot(color="white")  # for SkyCircularAperture
        aper_annulus.to_pixel(w).plot(color="red", linestyle="dashed")
        plt.xlabel("RA")
        plt.ylabel("Dec")
        plt.colorbar()
        if plottitle is not None:
            plt.title(plottitle)

    return flux, flux_err, bkg_stddev * u.Unit("10^-17 erg cm-2 s-1"), apcor
Beispiel #2
0
def get_photometry_ingredients(fits_file, RAs, DECs, aperture_radii,
                               annuli_inner_radii, annuli_outer_radii):

    # Get data, wcs
    data, h = fits.getdata(fits_file, header=True)
    w = WCS(h)

    # Define positions where aperture photometry will be performed
    positions = SkyCoord(ra=RAs, dec=DECs, unit='deg')

    # Create apertures at positions for photometry
    aperture_sky = [
        SkyCircularAperture(positions, r=r) for r in aperture_radii
    ]

    # Turn apertures defined in sky coordinates into pixel coordinates
    aperture_pixel = [a_sky.to_pixel(wcs=w) for a_sky in aperture_sky]

    # Perform aperture photometry
    phot = aperture_photometry(data, aperture_pixel)

    # Get out Array of aperture sums and areas
    aperture_sums = []
    aperture_areas = []
    for ii in range(len(aperture_radii)):
        aperture_sums.append(phot['aperture_sum_' + str(ii)])
        aperture_areas.append(aperture_pixel[ii].area)

    background_medians = []
    # Get background medians
    for r_inner, r_outer in zip(annuli_inner_radii, annuli_outer_radii):

        # Define annulus aperture
        annulus_aperture_sky = SkyCircularAnnulus(positions,
                                                  r_in=r_inner,
                                                  r_out=r_outer)

        # Turn annulus defined in sky coordinates to pixel coordinates
        annulus_masks_pixel = annulus_aperture_sky.to_pixel(wcs=w)

        # Define annuli masks to get annuli values from data:
        annulus_masks = annulus_masks_pixel.to_mask(method='center')

        # Get median background value around each apperture position
        bkg_median = []
        for mask in annulus_masks:
            annulus_data = mask.multiply(data)
            annulus_data_1d = annulus_data[mask.data > 0]
            _, median_sigclip, _ = sigma_clipped_stats(annulus_data_1d)
            bkg_median.append(median_sigclip)
        bkg_median = np.array(bkg_median)
        background_medians.append(bkg_median)

    return np.array(aperture_sums), np.array(aperture_areas), np.array(
        background_medians)
    def ap_phot(inp_img, rad_ap, rad_sky_i, rad_sky_o, show_plot=True):
        # Define Aperture Pars ===========
        ap = SkyCircularAperture(inp_img['coords_sky'],
                                 r=rad_ap)  # Roughly WISE4 PSF
        sky = SkyCircularAnnulus(inp_img['coords_sky'],
                                 r_in=rad_sky_i,
                                 r_out=rad_sky_o)
        ap_px = ap.to_pixel(wcs=inp_img['wcs'])
        sky_px = sky.to_pixel(wcs=inp_img['wcs'])

        # Perform Photometry =============
        phot_dat = aperture_photometry(inp_img['data'], ap, wcs=inp_img['wcs'])
        phot_sky = aperture_photometry(inp_img['data'],
                                       sky,
                                       wcs=inp_img['wcs'])
        bkg_mean = phot_sky['aperture_sum'] / sky_px.area()
        phot_dat['Phot'] = phot_dat['aperture_sum'] - (bkg_mean * ap_px.area())

        # Compute S/N ====================
        sky_stats = sample_comp.get_photmask_stats(sky_px,
                                                   inp_img=inp_img['data'])
        ap__stats = sample_comp.get_photmask_stats(ap_px,
                                                   inp_img=inp_img['data'])
        phot_dat['SN'] = (ap__stats['max'] -
                          sky_stats['mean']) / sky_stats['std']

        for col in ['aperture_sum', 'Phot', 'SN']:
            phot_dat[col].format = '10.2f'

        if show_plot:
            fig = plt.figure(figsize=[7, 7])
            ax = plt.subplot(111)

            img = ax.imshow(inp_img['data'], origin='lower', cmap='viridis')
            ap_px.plot()
            sky_px.plot(color='red')
            plt.show()

        return {
            'phot_tab': phot_dat,
            'phot_ap_px': ap_px,
            'phot_sky_px': sky_px
        }
    #    phot_table = aperture_photometry(imdata, aperture,wcs=wcs)
    phot_table = aperture_photometry(imdata, aperture_pix)
    #    print(phot_table)
    #    print(phot_table.colnames)
    #   print(phot_table['sky_center'])
    #    print(phot_table['xcenter'])
    #    print(phot_table['ycenter'])
    aper_sum = phot_table['aperture_sum']
    phot_table[
        'aperture_sum'].info.format = '%.8g'  # for consistent table output

    aper_annu = SkyCircularAnnulus(positions, r_inner_as, r_outer_as)
    #    print(aper_annu)
    #    print(aper_annu.r_in)
    #    print(aper_annu.r_out)
    aper_annu_pix = aper_annu.to_pixel(wcs)
    #    print(aper_annu_pix)
    r_in_annu_pix = aper_annu_pix.r_in
    r_out_annu_pix = aper_annu_pix.r_out
    #    print(r_in_annu_pix,r_out_annu_pix)

    apper = [aperture_pix, aper_annu_pix]
    phot_annu_table = aperture_photometry(imdata, apper)
    #    print(phot_annu_table)
    #    print(phot_annu_table.colnames)
    aper_annu_sum0 = phot_annu_table['aperture_sum_0']
    #   print(aper_annu_sum0)
    aper_annu_sum1 = phot_annu_table['aperture_sum_1']
    #   print(aper_annu_sum1)
    bkg_mean = phot_annu_table['aperture_sum_1'] / aper_annu_pix.area
    #   print(bkg_mean)
Beispiel #5
0
# import the channel used map.
# fitsimage='NGC5258_12CO10_combine_uvrange_smooth_regrid21_nchan.fits'
# chans=fits_import(fitsimage)[1]
chans = 50
chans_10 = chans

# define the aperture
position = SkyCoord(dec=0.8309 * u.degree,
                    ra=204.9906 * u.degree,
                    frame='icrs')
center_sky = SkyCircularAperture(position, r=3 * u.arcsec)
center_pix = center_sky.to_pixel(wcs=wcs)
apertures['center'] = center_pix

ring_sky = SkyCircularAnnulus(position, r_in=3 * u.arcsec, r_out=7 * u.arcsec)
ring_pix = ring_sky.to_pixel(wcs=wcs)
apertures['ring'] = ring_pix

position = SkyCoord(dec=0.8340 * u.degree,
                    ra=204.9935 * u.degree,
                    frame='icrs')
northarm_sky = SkyEllipticalAperture(position,
                                     a=13 * u.arcsec,
                                     b=4 * u.arcsec,
                                     theta=185 * u.degree)
northarm_pix = northarm_sky.to_pixel(wcs=wcs)
apertures['northarm'] = northarm_pix

position = SkyCoord(dec=0.8283 * u.degree,
                    ra=204.9882 * u.degree,
                    frame='icrs')
Beispiel #6
0
    def app_phot(self, imagefile, ras, decs, fwhm, plot=False, save=False):
        '''
        Computes the aperture photometry on the image, for the coordinates given.
        
        Parameters
        ----------
        imagefile : str
            The name of the fits file with the image.
        ras : array
            Array of floats with the RA positions for which aperture photometry is needed.
        decs : array
            Array of floats with the DEC positions for which aperture photometry is needed.
        fwhm : float
            Average FWHM of the field used to compute the aperture.
        plot : boolean
            Shall the apertures be plotted in the plot directory?
        save : boolean
            Save the aperture measurement to a file.

        Returns
        -------
        
        phot : QTable
            A table of the photometry with the following columns:
    
            'id': The source ID.
            'xcenter', 'ycenter': The x and y pixel coordinates of the input aperture center(s).
            'celestial_center': 
             'aperture_sum': The sum of the values within the aperture.
             'aperture_sum_err': The corresponding uncertainty in the 'aperture_sum' values. Returned only if the input error is not None.

        '''
        data = fits.open(imagefile)[self.ext].data
        filt = fitsutils.get_par(imagefile, 'FILTER', self.ext)
        mjd = Time(fitsutils.get_par(imagefile, "DATE-OBS", ext=self.ext)).mjd
        zp = fitsutils.get_par(imagefile, 'ZP', self.ext)
        color = fitsutils.get_par(imagefile, 'COLOR', self.ext)
        kcoef = fitsutils.get_par(imagefile, 'KCOEF', self.ext)
        zperr = fitsutils.get_par(imagefile, 'ZPERR', self.ext)
        if zp is None:
            zp = 0
        if zperr is None:
            zperr = 0

        wcs = astropy.wcs.WCS(fits.open(imagefile)[self.ext].header)
        
        positions = SkyCoord(ras*u.deg, decs*u.deg, frame='icrs')
        
        # Set aperture radius to three times the fwhm radius
        aperture_rad = np.median(fwhm)*2* u.arcsec    
        aperture = SkyCircularAperture(positions, r=aperture_rad)
        
        annulus_apertures = SkyCircularAnnulus(positions, r_in=aperture_rad*2, r_out=aperture_rad*4)
    
        #Convert to pixels
        pix_aperture = aperture.to_pixel(wcs)
        pix_annulus = annulus_apertures.to_pixel(wcs)
        pix_annulus_masks = pix_annulus.to_mask(method='center')
        
        #Plot apertures
        from astropy.visualization import simple_norm
        
        try:
            if np.ndim(ras) == 0:
                c = wcs.wcs_world2pix(np.array([[ras, decs]]), 0)                
            else:
                c = wcs.wcs_world2pix(np.array([ras, decs]).T, 0)
        except ValueError:
            self.logger.error('The vectors of RAs, DECs could not be converted into pixels using the WCS!')
            self.logger.error(str(np.array([ras, decs]).T))
    
        if plot:
            x = c[:,0]
            y = c[:,1]
            
            plt.figure(figsize=(10,10))
            norm = simple_norm(data, 'sqrt', percent=99)
            plt.imshow(data, norm=norm)
            pix_aperture.plot(color='white', lw=2)
            pix_annulus.plot(color='red', lw=2)
            plt.xlim(x[0]-200, x[0]+200)
            plt.ylim(y[0]-200, y[0]+200)
            plt.title('Apertures for filter %s'%filt)
            plt.savefig(os.path.join(self._plotpath, "apertures_cutout_%s.png"%os.path.basename(imagefile)))
            plt.clf()
        
        #Divide each pixel in 5 subpixels to make apertures
        apers = [pix_aperture, pix_annulus]
        phot_table = aperture_photometry(data, apers, method='subpixel', subpixels=5)
        for col in phot_table.colnames:
            phot_table[col].info.format = '%.8g'  # for consistent table output
        
    
        bkg_median = []
        std_counts = []
        for mask in pix_annulus_masks:
            annulus_data = mask.multiply(data)
            annulus_data_1d = annulus_data[mask.data > 0]
            _, median_sigclip, stdv_clip = sigma_clipped_stats(annulus_data_1d)
            bkg_median.append(median_sigclip)
            std_counts.append(stdv_clip)
            
        bkg_median = np.array(bkg_median)
        std_counts = np.array(std_counts)
        
        phot = aperture_photometry(data, pix_aperture)
        phot['annulus_median'] = bkg_median
        phot['annulus_std'] = std_counts
        phot['aper_bkg'] = bkg_median * pix_aperture.area()
        phot['aper_sum_bkgsub'] = phot['aperture_sum'] - phot['aper_bkg']
    
    
        # Flux = Gain * Counts / Exptime.
        exptime = fitsutils.get_par(imagefile, 'EXPTIME', self.ext)
        gain = fitsutils.get_par(imagefile, self.gain_keyword, self.ext)
        
        flux =  gain * phot['aper_sum_bkgsub'] / exptime
        inst_mag = -2.5*np.log10(flux)
    
        phot['flux'] = flux
        phot['inst_mag'] = inst_mag
        
        #Noise is the poisson noise of the source plus the background noise for the extracted area
        err = np.sqrt (flux + pix_aperture.area() * std_counts**2)
    
        #Transform pixels to magnitudes
        flux2 = gain * (phot['aper_sum_bkgsub']+err) / exptime
        inst_mag2 = -2.5*np.log10(flux2)
        
        errmag = np.abs(inst_mag2 - inst_mag)
        
        phot['err_counts'] = err
        phot['err_mag'] = errmag
        
        for col in phot.colnames:
            phot[col].info.format = '%.8g'  # for consistent table output
        
        if save:
            appfile = os.path.join(self._photpath, fitsutils.get_par(imagefile, "OBJECT", self.ext)+".app.phot.txt")
            self.logger.info('Creating aperture photometry out file as %s'%appfile)
            #Save the photometry into a file
            if (not os.path.isfile(appfile)):
                with open(appfile, 'w') as f:
                    f.write("mjd filter instr_mag zp zperr color kcoef mag magerr\n")
            
    
            with open(appfile, 'a') as f:
                self.logger.info('Adding aperture photometry to file %s'%appfile)

                f.write("%.3f %s %.4f %.4f %.4f %s %.4f %.4f %.4f\n"%(mjd, filt, phot['inst_mag'].data[0], \
                    zp, zperr, color, kcoef, phot['inst_mag'].data[0]+ zp, phot['err_mag'].data[0]))


        return phot
Beispiel #7
0
    def plot_image(self, data, wcs, coords=None):
        """
        convience function to plot data on a wcs projection

        Input:
        data -    the data array
        wcs -     the WCS object
        coords -  the coordinates of the object for plotting (1x2 array, optional)
        """
        # set up the plot
        fig, axs = plt.subplots(1,
                                1,
                                figsize=(8, 8),
                                subplot_kw={'projection': wcs})

        # set up limits of the colour scale for plotting
        vmin = 1e-1
        vmax = np.max(data) * 0.9

        # plot
        axs.imshow(data,
                   cmap='magma',
                   interpolation='nearest',
                   origin='lower',
                   norm=LogNorm(vmin=vmin, vmax=vmax))

        #axs.scatter(coords[0], coords[1], transform=axs.get_transform('fk5'), s=20000, lw=2,
        #            edgecolor='white', facecolor='none')

        # define the apertures to plot (these are the same as in other functions)
        # SNR
        position = SkyCoord(self.ra_deg * u.degree,
                            self.dec_deg * u.degree,
                            frame='icrs')
        snr_aperture = SkyCircularAperture(position, r=self.radius * u.arcsec)
        snr_pix_aperture = snr_aperture.to_pixel(wcs)
        snr_pix_aperture.plot(color='white', lw=5, alpha=1.0)

        # BKG
        r = self.radius * u.arcsec
        r_in = r + (40. * u.arcsec)
        r_out = r + (100. * u.arcsec)
        bkg_ap = SkyCircularAnnulus(position, r_in=r_in, r_out=r_out)
        bkg_ap_pix = bkg_ap.to_pixel(wcs)
        bkg_ap_pix.plot(color='red', lw=3, ls='--', alpha=0.9)

        # MIRI Imager
        r = self.radius * u.arcsec
        r_in = r - (37. * u.arcsec)
        r_out = r + (37. * u.arcsec)
        arc_ap = SkyCircularAnnulus(position, r_in=r_in, r_out=r_out)
        arc_ap_pix = arc_ap.to_pixel(wcs)
        arc_ap_pix.plot(color='cyan', lw=3, ls=':', alpha=0.9)

        axs.set_facecolor('black')
        axs.coords.grid(True, color='white', ls='dotted')
        axs.coords[0].set_axislabel('Right Ascension (J2000)')
        axs.coords[1].set_axislabel('Declination (J2000)')

        # indicative MIRI FOV
        x = Angle(self.radius, u.arcsec)
        y = x.degree
        t3_pos = SkyCoord((self.ra_deg) * u.degree,
                          (self.dec_deg + y) * u.degree,
                          frame='icrs')
        ap3 = SkyRectangularAperture(t3_pos, 74 * u.arcsec, 113 * u.arcsec,
                                     0 * u.degree)
        ap3_pix = ap3.to_pixel(wcs)
        ap3_pix.plot(color='yellow', lw=3, ls='-', alpha=0.9)

        axs.set_facecolor('black')
        axs.coords.grid(True, color='white', ls='dotted')
        axs.coords[0].set_axislabel('Right Ascension (J2000)')
        axs.coords[1].set_axislabel('Declination (J2000)')

        # display the plot
        plt.tight_layout()

        # save as a pdf
        plot_name = os.path.join(
            str(self.name),
            str(self.name) + '_' + str(self.wavelength) + '.pdf')
        try:
            os.remove(plot_name)
        except:
            pass

        fig.savefig(plot_name, dpi=200)