Beispiel #1
0
    def flux_arc(self, my_image_file, Rad, test_src_coord, wavelength):

        r = Rad * u.arcsec
        arc_r_in = r - (37. * u.arcsec)
        arc_r_out = r + (37. * u.arcsec)
        bkg_r_in = r * 1.1
        bkg_r_out = r * 1.25

        # load the file data, header, and wcs
        with fits.open(my_image_file) as hdulist:
            my_hdu = hdulist[0]
            my_hdu.data = np.nan_to_num(my_hdu.data)
            pixel_area = my_hdu.header['PXSCAL1']**2

            position = SkyCoord(test_src_coord[0] * u.degree,
                                test_src_coord[1] * u.degree,
                                frame='icrs')

            print('Running arc aperture photometry {}-{} um'.format(
                self.name, str(wavelength)))
            arc_ap = SkyCircularAnnulus(position,
                                        r_in=arc_r_in,
                                        r_out=arc_r_out)
            phot_table_arc = aperture_photometry(my_hdu, arc_ap)

            bkg_ap = SkyCircularAnnulus(position,
                                        r_in=bkg_r_in,
                                        r_out=bkg_r_out)
            phot_table_bkg = aperture_photometry(my_hdu, bkg_ap)

            # bkg subtract
            flux_bkg_sub = phot_table_arc['aperture_sum'] - phot_table_bkg[
                'aperture_sum']

        # convert to Jy
        if flux_bkg_sub.value > 0:

            ujy_arcsec = flux_bkg_sub.value * 23.5045
            Jy = ujy_arcsec * pixel_area * 1.e-06
            Jy = Jy[0]

            erg = (Jy * 1.e-23) * (2.997924e14 / ((wavelength)**2))

            # we must divide the circumference by the MIRI imager FOV height to get
            # average flux in a MIRI Imager FOV
            circum = 2 * np.pi * Rad
            n_miri_ima = circum / 113.

            self.arc_flux_Jy = Jy / n_miri_ima
            self.arc_flux_erg = erg / n_miri_ima

        else:
            self.arc_flux_Jy = 0.0
            self.arc_flux_erg = 0.0

        return self.arc_flux_erg
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 aperature_f(field, band, aper_rad=2., annu_in=3., annu_out=6.):

    hdu = fits.open("final/coadd_c%s_%s.fits" % (field, band))

    pos_filename = os.path.join('final', 'test%s_%s.fits' % (field, 'i'))
    if not os.path.isfile(pos_filename):
        print 'sextracting the i band position for %s' % field
        pos_filename = sex_band(field, 'i')

    t7 = Table.read(pos_filename)
    positions = SkyCoord(t7['XWIN_WORLD'], t7['YWIN_WORLD'], frame='icrs')
    apertures = SkyCircularAperture(positions, r=aper_rad * u.arcsec)
    annulus_apertures = SkyCircularAnnulus(positions,
                                           r_in=annu_in * u.arcsec,
                                           r_out=annu_out * u.arcsec)
    apers = [apertures, annulus_apertures]

    phot_table = aperture_photometry(hdu[0], apers)
    phot_table2 = phot_table[np.isfinite(phot_table['aperture_sum_0'])]
    phot_table3 = phot_table2[np.where(phot_table2['aperture_sum_0'] > 0)]

    snr = phot_table3['aperture_sum_0'] / (np.sqrt(
        phot_table3['aperture_sum_0']))
    phot_table3['snr'] = snr

    for name in phot_table3.colnames[1:]:
        phot_table3.rename_column(name, name + '_%s' % band)
    return phot_table3
Beispiel #4
0
def photometry():

    filters = ['I', 'B', 'V', 'R']  #filter names

    # create a table here for Photometry results
    photo_table = Table(names=('Residuals', 'Error', 'Time'))
    Photometry = open('photometry_' + str(sn_name) + '.txt', 'w')

    for f in filters:

        #create a txt file where the Photometry Results table will be saved

        #join the two paths given above
        search_str = os.path.join(date_search_path,
                                  str(sn_name) + str(f) + '.fits')

        #names will be the supernova fits files for different filters
        for name in glob(search_str):

            with fits.open(name) as analysis:

                N = analysis[0].header[
                    'NCOMBINE']  # number of images stacked in the fit file
                final_date = convert_time(
                    analysis)  # The Time series must be MJD

                #Position of Supernova as coordinate, aperture is calculated with the coordinate
                cordinate = SkyCoord('01:48:08.66 +37:33:29.22',
                                     unit=(u.hourangle, u.deg))
                #coordinates = SkyCoord('01:48:08.66 +37:33:29.22',unit = (u.hourangle, u.deg))

                #exp_time= analysis[0].header['EXPTIME']
                #data_error = np.sqrt(N*analysis[0].data)

                aperture = SkyCircularAperture(cordinate, r=5 * u.arcsec)
                annulus_apertures = SkyCircularAnnulus(cordinate,
                                                       r_in=6 * u.arcsec,
                                                       r_out=8 * u.arcsec)

                aperture_area = np.pi * 3**2
                annulus_area = np.pi * (8**2 - 6**2)

                rawflux_table = aperture_photometry(analysis[0], aperture)
                bkgflux_table = aperture_photometry(analysis[0],
                                                    annulus_apertures)

                residual_sum = rawflux_table[0]['aperture_sum'] - bkgflux_table[
                    0]['aperture_sum'] * aperture_area / annulus_area
                error = np.sqrt(np.abs(residual_sum) * N)
                photo_table.add_row((residual_sum, error, final_date))

    print "***** Photometry Results without Calibration ****"
    print photo_table
    print >> Photometry, photo_table
    Photometry.close()
    calibration(N)
    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
        }
Beispiel #6
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 #7
0
    def set_mask(
        self,
        *args,
        method: str = "source",
        inner: float = None,
        outer: float = None,
        position: SkyCoord = None,
        wcs: WCS = None,
        **kwargs,
    ):
        """
        Set a mask to the data image

        :param method: the method to set mask, "source", or "annulus"defaults to "source"
        :type method: str, optional
        :param inner: the inner radius of the annulus, defaults to None
        :type inner: float, optional
        :param outer: the outer radius of the annulus, defaults to None
        :type outer: float, optional
        :param position: the center of the annulus, defaults to None
        :type position: SkyCoord, optional
        :param wcs: the wcs used to convert mask to pixel, defaults to None
        :type wcs: WCS, optional
        :raises ValueError: "annulus" must have position and inner/outer radius
        """

        if method == "source":
            self._mask = make_source_mask(self.data, *args, **kwargs)

        elif method == "annulus":
            if not position or not inner or not outer:
                raise ValueError(
                    "Use annulus mask but missing position or inner/outer radius"
                )

            else:
                if not wcs:
                    logging.warning(
                        "Not assign the wcs, try the wcs from the header")
                    wcs = self.header

                mask = (SkyCircularAnnulus(
                    position, inner * u.arcsec,
                    outer * u.arcsec).to_pixel(wcs).to_mask("center"))
                self._mask = self.ImageMask(shape="annulus",
                                            position=position,
                                            rin=inner,
                                            rout=outer,
                                            mask=mask)
                # self.mask = self.aper.to_mask("center")

        else:
            raise ValueError(f"No supported method: {method}")
def simpleapphot(fileName, pos, r, rI, rO, frame='image'):
    '''Performs simple circular aperture photometry with local bg subtraction
    '''

    # Check Type of pos first
    if not isinstance(pos, np.ndarray): pos = np.array(pos)

    if pos.ndim == 1:
        pos = pos.reshape((-1, 2))

    # Create Aperture
    frame = frame.lower()
    if frame == 'image':

        # Create the Aperatures
        cirAps = CircularAperture(pos, r)
        annAps = CircularAnnulus(pos, rI, rO)

    elif frame == 'fk5':

        # Create Sky Apertures
        pos = SkyCoord(frame=frame,
                       ra=pos[:, 0] * u.deg,
                       dec=pos[:, 1] * u.deg)
        cirAps = SkyCircularAperture(pos, r * u.arcsec)
        annAps = SkyCircularAnnulus(pos, rI * u.arcsec, rO * u.arcsec)

    else:
        raise ValueError('Unsupported coordinate system.')

    # Load in the files and do photometry
    hdu = fits.open(fileName)
    cirPhotTab = aperture_photometry(hdu, cirAps)
    annPhotTab = aperture_photometry(hdu, annAps)
    if frame == 'fk5':
        cirAps = cirAps.to_pixel(WCS(header=hdu['SCI'].header))
        annAps = annAps.to_pixel(WCS(header=hdu['SCI'].header))
    hdu.close()

    # Get Photometry as ndarray
    phot = cirPhotTab['aperture_sum'].data - \
           (cirAps.area()/annAps.area())*annPhotTab['aperture_sum'].data
    return phot
Beispiel #9
0
def set_apertures(catalog, limit=16, r=10, r_in=15.5, r_out=25):
    '''
    From Anna Marini: get a catalog and
    set apertures and annulus for photometry.
    '''
    radec = catalog['ra', 'dec', 'phot_g_mean_mag']
    mask = radec['phot_g_mean_mag'] < limit
    radec = radec[mask]

    positions = SkyCoord(radec['ra'],
                         radec['dec'],
                         frame='fk5',
                         unit=(u.deg, u.deg))

    aperture = SkyCircularAperture(positions, r=r * u.arcsec)
    annulus = SkyCircularAnnulus(positions,
                                 r_in=r_in * u.arcsec,
                                 r_out=r_out * u.arcsec)
    apers = [aperture, annulus]

    return apers
Beispiel #10
0
    def ap_phot(self, my_image_file, Rad, test_src_coord, wavelength):
        """
        ap_phot applies aperture photometry to calculate the flux of the source. It creates a circle aperture around
        the source referencing the radius of the snr as the radius of the circular aperture. It also creates 4 more
        apertures away from the source which are then averaged and subtracted from the target flux to remove background

        Input
        ==========================
        my_image_files (.fits):
            .fits file from coordinates

        Rad (float):
            radius in units of arcsec

        test_src_coord (float):
            coordinates of target in decimal degrees

        wavelength (float):
            waveband in units of um

        Output
        ==========================
        FluxIR (float):
            calculated flux in units of erg/s/cm^2
        """

        fluxes = []

        r = Rad * u.arcsec
        r_in = r + (40. * u.arcsec)
        r_out = r + (100. * u.arcsec)

        # load the file data, header, and wcs
        with fits.open(my_image_file) as hdulist:
            my_hdu = hdulist[0]
            my_hdu.data = np.nan_to_num(my_hdu.data)
            pixel_area = my_hdu.header['PXSCAL1']**2

            print('Running aperture photometry {}-{} um'.format(
                self.name, str(wavelength)))
            position = SkyCoord(test_src_coord[0] * u.degree,
                                test_src_coord[1] * u.degree,
                                frame='icrs')
            apertures = SkyCircularAperture(position, r=Rad * u.arcsec)
            phot_table = aperture_photometry(my_hdu, apertures)
            fluxes.append(phot_table['aperture_sum'])
            #print(phot_table['aperture_sum'])

            print('Running background aperture photometry {}-{} um'.format(
                self.name, str(wavelength)))

            bkg_ap = SkyCircularAnnulus(position, r_in=r_in, r_out=r_out)
            phot_table_bkg = aperture_photometry(my_hdu, bkg_ap)
            #print(phot_table_bkg['aperture_sum'])

            # bkg subtract
            flux_bkg_sub = phot_table['aperture_sum'] - phot_table_bkg[
                'aperture_sum']

        # convert to Jy
        if flux_bkg_sub.value > 0:
            ujy_arcsec = flux_bkg_sub.value * 23.5045
            Jy = ujy_arcsec * pixel_area * 1.e-06
            Jy = Jy[0]

            erg = (Jy * 1.e-23) * (2.997924e14 / ((wavelength)**2))

            self.flux_Jy = Jy
            self.flux_erg = erg

        else:
            erg = 0.0

            self.flux_Jy = 0.0
            self.flux_erg = 0.0

        return erg
Beispiel #11
0
def qphot(data,
          coord,
          rad,
          skyradin,
          skyradout,
          wcs=None,
          calfctr=None,
          skycoord=None,
          unit='Jy',
          error=None,
          filter=None):
    if is_pix_coord(coord):
        coord = [np.float(coord[0]), np.float(coord[1])]
        aperture = CircularAperture(coord, r=rad)
    else:
        coord = SkyCoord(' '.join(coord),
                         unit=(u.hourangle, u.deg),
                         frame='icrs')
        aperture = SkyCircularAperture(coord, r=rad * u.arcsec)

    if skycoord:
        if is_pix_coord(skycoord):
            scoord = [np.float(skycoord[0]), np.float(skycoord[1])]
            annulus = CircularAnnulus(scoord, skyradin, skyradout)
        else:
            scoord = SkyCoord(' '.join(skycoord),
                              unit=(u.hourangle, u.deg),
                              frame='icrs')
            annulus = SkyCircularAnnulus(scoord, skyradin * u.arcsec,
                                         skyradout * u.arcsec)
    else:
        if isinstance(coord, SkyCoord):
            annulus = SkyCircularAnnulus(coord, skyradin * u.arcsec,
                                         skyradout * u.arcsec)
        else:
            annulus = CircularAnnulus(coord, skyradin, skyradout)

    #mask out nans or negative
    mask = np.logical_or(np.isnan(data), data < 0.)

    apflux = aperture_photometry(data,
                                 aperture,
                                 wcs=wcs,
                                 error=error,
                                 mask=mask)
    skyflux = aperture_photometry(data,
                                  annulus,
                                  wcs=wcs,
                                  error=error,
                                  mask=mask)
    phot_table = hstack([apflux, skyflux], table_names=['src', 'sky'])

    #calculate mean local background in annulus
    if isinstance(annulus, SkyCircularAnnulus):
        sky_area = annulus.to_pixel(wcs).area()
    else:
        sky_area = annulus.area()

    if isinstance(aperture, SkyCircularAperture):
        src_area = aperture.to_pixel(wcs).area()
    else:
        src_area = aperture.area()
    sky_mean = phot_table['aperture_sum_sky'] / sky_area
    sky_sum = sky_mean * src_area

    final_sum = phot_table['aperture_sum_src'] - sky_sum
    phot_table['residual_aperture_sum'] = final_sum
    phot_table['residual_aperture_sum'].unit = unit
    phot_table['aperture_area_sky'] = sky_area
    phot_table['aperture_area_src'] = src_area
    phot_table['aperture_mean_sky'] = sky_mean
    phot_table['aperture_mean_sky'].unit = unit
    phot_table['aperture_rad_src'] = rad
    phot_table['aperture_irad_sky'] = skyradin
    phot_table['aperture_orad_sky'] = skyradout
    phot_table['aperture_area_sky'].unit = u.pix**2
    phot_table['aperture_area_src'].unit = u.pix**2

    if error is not None:
        src_err = phot_table['aperture_sum_err_src']
        sky_err = phot_table['aperture_sum_err_sky']
        src_var = src_err / phot_table['residual_aperture_sum']
        sky_var = sky_err / sky_sum
        color_err = 0.  # 10 percent photoerr
        color_var = color_err * phot_table['residual_aperture_sum']
        phot_table['residual_aperture_err'] = np.sqrt(src_var**2 + sky_var**2 +
                                                      color_var**2)

    else:
        color_err = 0.07  # 7 percent photoerr
        color_var = color_err * sky_sum
        phot_table.add_column(
            Column([color_var for x in phot_table],
                   name='residual_aperture_err'))

    phot_table.remove_columns(
        ['xcenter_src', 'ycenter_src', 'xcenter_sky', 'ycenter_sky'])
    if 'center_input' in phot_table.colnames:
        phot_table.remove_columns('center_input')
    if 'center_input_src' in phot_table.colnames:
        phot_table.remove_columns('center_input_src')
    if 'center_input_sky' in phot_table.colnames:
        phot_table.remove_columns('center_input_sky')

    if isinstance(coord, SkyCoord):
        phot_table['xcen'], phot_table['ycen'] = wcs2pix(coord, wcs)
        phot_table['ra'], phot_table['dec'] = coord.to_string('hmsdms',
                                                              sep=':').split()
    else:
        phot_table['xcen'] = coord[0]
        phot_table['ycen'] = coord[1]

    if skycoord:
        if isinstance(scoord, SkyCoord):
            phot_table['xcensky'], phot_table['ycensky'] = wcs2pix(scoord, wcs)
            phot_table['rasky'], phot_table['decsky'] = scoord.to_string(
                'hmsdms', sep=':').split()
        else:
            phot_table['xcensky'] = scoord[0]
            phot_table['ycensky'] = scoord[1]

    if wcs:
        if 'ra' not in phot_table.colnames:
            ra, dec = pix2wcs(coord, wcs)
            phot_table['ra'] = ra
            phot_table['dec'] = dec

        if skycoord:
            if 'rasky' not in phot_table.colnames:
                skyra, skydec = pix2wcs(scoord, wcs)
                phot_table['rasky'] = skyra
                phot_table['decsky'] = skydec

    if calfctr:
        flux = phot_table['residual_aperture_sum'] / calfctr
        phot_table.add_column(Column(flux, name='ap_flux', unit=unit))

        #if error is not None:
        fluxerr = phot_table['residual_aperture_err'] / calfctr
        phot_table.add_column(Column(fluxerr, name='ap_err', unit=unit))

    if filter:
        phot_table['filter'] = str(filter)

    return phot_table
Beispiel #12
0
def extract_photometry(ccddata,
                       catalog,
                       catalog_coords,
                       target,
                       image_path=None,
                       aperture_radius=2. * u.arcsec,
                       bg_radius_in=None,
                       bg_radius_out=None):
    apertures = SkyCircularAperture(catalog_coords, aperture_radius)
    if bg_radius_in is not None and bg_radius_out is not None:
        apertures = [
            apertures,
            SkyCircularAnnulus(catalog_coords, bg_radius_in, bg_radius_out)
        ]
    photometry = aperture_photometry(ccddata, apertures)
    target_row = photometry[target][0]
    if target_row['xcenter'].value < 0. or target_row['xcenter'].value > ccddata.shape[1] or \
            target_row['ycenter'].value < 0. or target_row['ycenter'].value > ccddata.shape[0]:
        logging.error(
            'target not contained in the image (or coordinate solution is bad)'
        )
        return
    if 'aperture_sum_1' in photometry.colnames:
        flux = photometry['aperture_sum_0'] - photometry['aperture_sum_1']
        dflux = (photometry['aperture_sum_err_0']**2. +
                 photometry['aperture_sum_err_1']**2.)**0.5
    else:
        flux = photometry['aperture_sum']
        dflux = photometry['aperture_sum_err']
    photometry['aperture_mag'] = u.Magnitude(flux / ccddata.meta['exptime'])
    photometry['aperture_mag_err'] = 2.5 / np.log(10.) * dflux / flux
    photometry = hstack([catalog, photometry])
    photometry['zeropoint'] = photometry['catalog_mag'] - photometry[
        'aperture_mag'].value
    zeropoints = photometry['zeropoint'][~target].filled(np.nan)
    zp = np.nanmedian(zeropoints)
    zperr = mad_std(
        zeropoints,
        ignore_nan=True) / np.isfinite(zeropoints).sum()**0.5  # std error
    target_row = photometry[target][0]
    mag = target_row['aperture_mag'].value + zp
    dmag = (target_row['aperture_mag_err'].value**2. + zperr**2.)**0.5
    with open(lc_file, 'a') as f:
        f.write(
            f'{ccddata.meta["MJD-OBS"]:11.5f} {mag:6.3f} {dmag:5.3f} {zp:6.3f} {zperr:5.3f} {ccddata.meta["FILTER"]:>6s} '
            f'{ccddata.meta["TELESCOP"]:>16s} {ccddata.meta["filename"]:>22s}\n'
        )

    if image_path is not None:
        ax = plt.axes()
        mark = ',' if np.isfinite(
            photometry['aperture_mag']).sum() > 1000 else '.'
        ax.plot(photometry['aperture_mag'],
                photometry['catalog_mag'],
                ls='none',
                marker=mark,
                zorder=1,
                label='calibration stars')
        ax.plot(mag - zp, mag, ls='none', marker='*', zorder=3, label='target')
        yfit = np.array([21., 13.])
        xfit = yfit - zp
        ax.plot(xfit, yfit, label=f'$Z = {zp:.2f}$ mag', zorder=2)
        ax.set_xlabel('Instrumental Magnitude')
        ax.set_ylabel('AB Magnitude')
        ax.legend()
        plt.savefig(image_path, overwrite=True)
        plt.savefig('latest_cal.pdf', overwrite=True)
        plt.close()

        plt.figure(figsize=(6., 6.))
        imshow_norm(ccddata.data, interval=ZScaleInterval())
        plt.axis('off')
        plt.axis('tight')
        plt.tight_layout(pad=0.)
        if isinstance(apertures, list):
            for aperture in apertures:
                aperture.to_pixel(ccddata.wcs).plot(color='r', lw=1)
        else:
            apertures.to_pixel(ccddata.wcs).plot(color='r', lw=1)
        image_filename = ccddata.meta['filename'].replace('.fz', '').replace(
            '.fits', '.png')
        plt.savefig(os.path.join(image_dir, image_filename), overwrite=True)
        plt.savefig('latest_image.png', overwrite=True)
        plt.close()
Beispiel #13
0
def generate_regions(hdu,
                     approx_location,
                     centering_width=80,
                     ap_rad=6.5,
                     in_rad=7.0,
                     out_rad=14.0):
    """
    Generates source and background regions for aperture photometry. 
    Given an image and the approximate RA/Dec of the source, finds the 
    centroid within centering_width pixels and generates regions with 
    the given parameters
    
    Parameters
    ----------
    hdu : `~astropy.io.fits.hdu.image.PrimaryHDU`
        HDU object containing the FITS image from which regions are generated.
        Should be just the primary hdu (e.g., hdu[0]).
    approx_location : `~astropy.coordinates.SkyCoord`
        `astropy.coordinates.SkyCoord` with the RA and Dec of the object you 
        want to generate a region for.
    centering_width : int, optional
        Size of box around source region to find the centroid of in pixels.
    ap_rad : float, optional
        Radius of source region in arcseconds.
    in_rad : float, optional
        Inner radius of background annulus in arcseconds
    out_rad : float, optional
        Outer radius of background annulus in arcseconds
    
        
    Returns
    -------
    src : `~photutils.SkyCircularAperture`
        Aperture object for source
    bkg : `~photutils.SkyCircularAnnulus`
        Aperture object for background
        
    """

    #Make data and wcs objects
    data = hdu.data
    wcs = WCS(hdu)

    #Make the right shape array of coordinates
    world_loc = np.array(
        [[approx_location.ra.value, approx_location.dec.value]])

    #Convert to pixel coordinates from the FITS image, 0 indexed b.c. we're working with
    #a numpy array
    approx_pix = wcs.wcs_world2pix(world_loc, 0)[0]

    #Convert to pixel locations of the window.
    min_x = int(approx_pix[0] - centering_width / 2.0)
    min_y = int(approx_pix[1] - centering_width / 2.0)
    max_x = int(approx_pix[0] + centering_width / 2.0)
    max_y = int(approx_pix[1] + centering_width / 2.0)

    #Make a little cutout around the object
    #Numpy arrays are weird, so x->y, y->x
    stamp = data[min_y:max_y, min_x:max_x]

    #Calculate the centroid of the stamp
    x_stamp_centroid, y_stamp_centroid = centroid_com(stamp)

    #Add back in the boundaries of the box to get centroid in data coords
    x_centroid = x_stamp_centroid + min_x
    y_centroid = y_stamp_centroid + min_y

    #Convert back to RA/Dec. Remember, these are 0-indexed pixels.
    centroid = wcs.wcs_pix2world(np.array([[x_centroid, y_centroid]]), 0)

    #Convert centroid to SkyCoords object
    location = SkyCoord(ra=centroid[0, 0] * u.degree,
                        dec=centroid[0, 1] * u.degree)

    #Generate regions based on coordinates and given radii.
    src = SkyCircularAperture(location, r=ap_rad * u.arcsecond)
    bkg = SkyCircularAnnulus(location,
                             r_in=in_rad * u.arcsecond,
                             r_out=out_rad * u.arcsecond)

    return src, bkg
Beispiel #14
0
def cal_image(img_path):
    image_path = os.path.join(basepath, img_path)

    # load img with WCS
    if not '.new' in image_path:
        img = image_path.strip('.fits') + '.new'
    else:
        img = image_path

    fits_file = fits.open(img, mode='update')
    hdr = fits_file[0].header #fits.getheader(img)
    data = fits_file[0].data  # fits.getdata(img)
    wcs = WCS(hdr)

    # Obtain image center
    crval_ra= hdr['CRVAL1']
    crval_dec = hdr['CRVAL2']
    crval_x = hdr['CRPIX1']
    crval_y = hdr['CRPIX2']

    # Get sources in image
    mask = make_source_mask(data, snr=2, npixels=5, dilate_size=11)
    mask_zeros = data==0
    mask = mask | mask_zeros

    mean, median, std = sigma_clipped_stats(data, sigma=3.0, mask=mask)
    sigma_clip = SigmaClip(sigma=3., iters=10)
    bkg_estimator = MedianBackground()
    bkg_estimator = SExtractorBackground()

    bkg = Background2D(data, (50, 50), filter_size=(3, 3),
                       sigma_clip=sigma_clip,
                       bkg_estimator=bkg_estimator,
                       mask=mask)

    back = bkg.background * ~mask

    daofind = DAOStarFinder(fwhm=5.0, threshold=5.*std)
    sources = daofind(data - median)
    #print(sources)

    positions = (sources['xcentroid'], sources['ycentroid'])
    xypos = np.array([sources['xcentroid'], sources['ycentroid']]).T
    sky_pos = wcs.all_pix2world(xypos, 0)
    skycoords = coord.SkyCoord(sky_pos*u.deg, frame='icrs')

    radii = [5.*u.arcsec, 7.*u.arcsec, 10.*u.arcsec]
    annulus = [(6.*u.arcsec, 8.*u.arcsec),
               (9.*u.arcsec, 11.*u.arcsec),
               (11.*u.arcsec, 12.*u.arcsec)]

    apertures = [SkyCircularAperture(skycoords, r=r).to_pixel(wcs)
                 for r in radii]
    annulii = [SkyCircularAnnulus(skycoords, r_in=ri, r_out=ro).to_pixel(wcs)
               for ri, ro in annulus]
    apers = apertures + annulii

    #~ tables = [aperture_photometry(data-back, aper) for aper in apers]
    phot_table = aperture_photometry(data-back, apers)

    bkg_sum_0 = apertures[0].area()*phot_table['aperture_sum_3']/annulii[0].area()
    bkg_sum_1 = apertures[0].area()*phot_table['aperture_sum_4']/annulii[1].area()
    bkg_sum_2 = apertures[0].area()*phot_table['aperture_sum_5']/annulii[2].area()

    final_sum_0 = phot_table['aperture_sum_0'] - bkg_sum_0
    final_sum_1 = phot_table['aperture_sum_1'] - bkg_sum_1
    final_sum_2 = phot_table['aperture_sum_2'] - bkg_sum_2

    phot_table['resid_aper_sum_0'] = final_sum_0
    phot_table['resid_aper_sum_1'] = final_sum_1
    phot_table['resid_aper_sum_2'] = final_sum_2

    phot_table['cmag_0'] = -2.5 * np.log10(final_sum_0)
    phot_table['cmag_1'] = -2.5 * np.log10(final_sum_1)
    phot_table['cmag_2'] = -2.5 * np.log10(final_sum_2)

    phot_table['mag_0'] = -2.5 * np.log10(phot_table['aperture_sum_0'])
    phot_table['mag_1'] = -2.5 * np.log10(phot_table['aperture_sum_1'])
    phot_table['mag_2'] = -2.5 * np.log10(phot_table['aperture_sum_2'])

    phot_table['RA'] = skycoords.ra
    phot_table['Dec'] = skycoords.dec

    # match the catalogs
    # attempt a xmatch
    phot_table.write('/tmp/sourcecat.csv', overwrite=True)
    try:
        from astroquery.xmatch import XMatch
        XMatch.TIMEOUT = 600
        try:
            table = XMatch.query(cat1=open('/tmp/sourcecat.csv'),
                             #cat2='vizier:II/336/apass9', #apass
                             cat2='vizier:I/322A/out',   # UCAC4
                             #cat2='vizier:II/246/out',   # 2MASS
                             max_distance=5 * u.arcsec,
                             colRA1='RA',
                             colDec1='Dec',
                             colRA2='RAJ2000',
                             colDec2='DEJ2000')
            print 'Using UCAC4'
            print table.colnames
            if 'Rmag' not in table.colnames and 'rmag' in table.colnames:
                table['Rmag'] = table['rmag']
        except:
            try:
                table = XMatch.query(cat1=open('/tmp/sourcecat.csv'),
                                 cat2='vizier:II/336/apass9', #apass
                                 #cat2='vizier:I/322A/out',   # UCAC4
                                 #cat2='vizier:II/246/out',   # 2MASS
                                 max_distance=5 * u.arcsec,
                                 colRA1='RA',
                                 colDec1='Dec',
                                 colRA2='RAJ2000',
                                 colDec2='DEJ2000')
                print 'Using APASS'
                print table.colnames
                if 'Rmag' not in table.colnames and 'rmag' in table.colnames:
                    table['Rmag'] = table['rmag']
            except:

                try:
                    table = XMatch.query(cat1=open('/tmp/sourcecat.csv'),
                                     #cat2='vizier:II/336/apass9', #apass
                                     #cat2='vizier:I/322A/out',   # UCAC4
                                     cat2='vizier:II/246/out',   # 2MASS
                                     max_distance=5 * u.arcsec,
                                     colRA1='RA',
                                     colDec1='Dec',
                                     colRA2='RAJ2000',
                                     colDec2='DEJ2000')
                    print 'Using 2MASS'
                    print table.colnames
                    if 'Rmag' not in table.colnames and 'rmag' in table.colnames:
                        table['Rmag'] = table['rmag']
                except:
                    print('\ntable 1 avaliable?:')
                    print XMatch.is_table_available('vizier:II/336/apass9')
                    print('\ntable 2 avaliable?:')
                    print XMatch.is_table_available('vizier:I/322A/out')
                    print('\ntable 3 avaliable?:')
                    print XMatch.is_table_available('vizier:II/246/out')
                    raise
    except:
        # query PanSTARRS DR1
        #~ catalog = panstarrs_query(crval_ra, crval_dec, 0.5, maxsources=300)
        #~ if len(ps1_tab) < 20:
            #~ from astroquery.vizier import Vizier
            #~ catalog = Vizier.query_region(coord.SkyCoord(crval_ra*u.deg,
                                                         #~ crval_dec*u.deg,
                                                         #~ frame='icrs'),
                                          #~ radius=coord.Angle(0.3, "deg"),
                                          #~ catalog='UCAC4')[0]
        #~ ra = catalog['RAJ2000']
        #~ dec = catalog['DEJ2000']
        #~ cat = coord.SkyCoord(ra, dec, frame='icrs')
        #~ # cat to sources
        #~ idx_c2s, d2d_c2s, _ = skycoords.match_to_catalog_sky(cat)
        #~ # sources to cat
        #~ idx_s2c, d2d_s2c, _ = cat.match_to_catalog_sky(skycoords)
        #~ matches = cat[idx_c2s] # same length than skycoords
        #~ idx_c2s[idx_s2c]
        raise

    from sklearn import linear_model
    if 'UCAC4' in table.colnames:
        table['color'] = table['Bmag'] - table['Vmag']
    if '2MASS' in table.colnames:
        table['color'] = table['Jmag'] - table['Kmag']
        table['Bmag'] = table['Jmag']


    # V Mag
    plt.subplot(221)
    reg = linear_model.LinearRegression()
    sub = table[['mag_1', 'Vmag']].to_pandas()
    sub = sub.dropna(axis=0, how='any')
    X = sub[['mag_1']].as_matrix()
    Y = sub['Vmag'].as_matrix()
    reg.fit(X,Y)
    print reg.coef_, reg.intercept_
    regV = reg
    table['pred_Vmag'] = reg.coef_*table['mag_1']+reg.intercept_
    plt.plot(table['mag_1'], table['Vmag'], 'r.')
    plt.plot(table['mag_1'], table['pred_Vmag'], 'k-', label='linear fit')
    plt.xlabel('mag_1')
    plt.ylabel('Vmag')
    plt.grid()

    # B mag
    plt.subplot(222)
    reg = linear_model.LinearRegression()
    sub = table[['mag_1', 'Bmag']].to_pandas()
    sub = sub.dropna(axis=0, how='any')
    X = sub[['mag_1']].as_matrix()
    Y = sub['Bmag'].as_matrix()
    reg.fit(X,Y)
    print reg.coef_, reg.intercept_
    regB = reg
    table['pred_Bmag'] = reg.coef_*table['mag_1']+reg.intercept_
    plt.plot(table['mag_1'], table['Bmag'], 'r.')
    plt.plot(table['mag_1'], table['pred_Bmag'], 'k-', label='linear fit')
    plt.xlabel('mag_1')
    plt.ylabel('Bmag')
    plt.grid()

    # R mag
    plt.subplot(223)
    reg = linear_model.LinearRegression()
    sub = table[['mag_1', 'Rmag']].to_pandas()
    sub = sub.dropna(axis=0, how='any')
    X = sub[['mag_1']].as_matrix()
    Y = sub['Rmag'].as_matrix()
    reg.fit(X,Y)
    print reg.coef_, reg.intercept_
    regR = reg
    table['pred_Rmag'] = reg.coef_*table['mag_1']+reg.intercept_
    plt.plot(table['mag_1'], table['Rmag'], 'r.')
    plt.plot(table['mag_1'], table['pred_Rmag'], 'k-', label='linear fit')
    plt.xlabel('mag_1')
    plt.ylabel('Rmag')
    plt.grid()

    # Residuals vs B-V
    plt.subplot(224)
    plt.plot(table['color'], table['pred_Vmag']-table['Vmag'], 'g.', label='Vmag')
    plt.plot(table['color'], table['pred_Bmag']-table['Bmag'], 'b.', label='Bmag')
    plt.plot(table['color'], table['pred_Rmag']-table['Rmag'], 'r.', label='Rmag')
    plt.xlabel('color')
    plt.ylabel('Residual')
    plt.legend(loc='best')
    plt.grid()

    plt.tight_layout()
    plt.savefig(image_path.strip('.new')+'_calibration.png')
    plt.clf()

    hdr['ZP_R'] = regR.intercept_
    hdr['ZP_B'] = regB.intercept_
    hdr['ZP_V'] = regV.intercept_

    hdr['SLOPE_R'] = regR.coef_[0]
    hdr['SLOPE_B'] = regB.coef_[0]
    hdr['SLOPE_V'] = regV.coef_[0]

    chosen = {'band': None, 'res': 10}
    for band in ['R', 'B', 'V']:
        res = table['pred_'+band+'mag']-table[band+'mag']
        residual = np.sqrt(np.sum(np.square(res)))
        if residual < chosen['res']:
            chosen['res'] = residual
            chosen['band'] = band

    hdr['CAL_BAND'] = chosen['band']
    hdr['CAL_RES'] = chosen['res']

    fits_file.flush()
    fits_file.close()

    band = chosen['band']
    plt.hist(table['pred_'+band+'mag'])
    plt.xlabel('instrumental '+band+' mag')
    plt.savefig(image_path.strip('.new')+'_magnitudes.png')

    table.write(image_path.strip('.new')+'_sources.csv', overwrite=True)
    with open('calibrations.txt', 'a') as cals:
        cals.write(image_path)
        cals.write(' ')
        cals.write('{}'.format(np.max(table['pred_'+band+'mag'])))
        cals.write(' ')
        cals.write('{}'.format(np.std(table['pred_'+band+'mag'])))
        cals.write(' ')
        cals.write('{}'.format(hdr['ZP_R']))
        cals.write(' ')
        cals.write('{}'.format(hdr['ZP_B']))
        cals.write(' ')
        cals.write('{}'.format(hdr['ZP_V']))
        cals.write(' ')
        cals.write('{}'.format(hdr['SLOPE_R']))
        cals.write(' ')
        cals.write('{}'.format(hdr['SLOPE_B']))
        cals.write(' ')
        cals.write('{}'.format(hdr['SLOPE_V']))
        cals.write(' ')
        cals.write('{}'.format(hdr['CAL_BAND']))
        cals.write(' ')
        cals.write('{}'.format(hdr['CAL_RES']))
        cals.write('\n')

    print 'finished'
def calc_radial_profile(fitsfile, center, rstart, rend, rstep, verbose=False, detmaskfile=None, plot=True):
    """

    Utility function to calculate the radial profile from an image `fitsfile` at a `center`

    """
    #
    if (not os.path.isfile(fitsfile)):
        print(f"ERROR. FITS file {fitsfile} not found. Cannot continue.")
        return None
    #
    qhdu = fits.open(fitsfile)
    wcs = WCS(qhdu[0].header)
    #
    # if detmaskfile is provided then will use it for detector mask
    #
    doMask = False
    if (detmaskfile != None):
        if (not os.path.isfile(detmaskfile)):
            print(f"Warning. Detector mask file {detmaskfile} not found. Will not use detector mask!")
            doMask = False
        else:
            det = fits.open(detmaskfile)
            detmask = det['MASK']
            # need the WCS
            wcs_det = WCS(detmask.header)
            doMask = True
    #
    if (not isinstance(center, SkyCoord)):
        print(f"ERROR: the input radial profile centre is not SkyCoord object. Cannot continue.")
        return None
    #
    j = 0
    rx = rstart
    counts = []
    counts_err = []
    rmid = []
    #
    emtpy = False
    while rx < rend:
        r0 = rstart + rstep * j
        rx = rstart + rstep * (j + 1)
        # the mid point, can be better the mid area point
        rmid.append((r0.value + rx.value) / 2.0)
        if (j == 0):
            xap = SkyCircularAperture(center, rx)
            photo = aperture_photometry(qhdu[0].data, xap, wcs=wcs)
            if (doMask):
                masked = aperture_photometry(detmask.data, xap, wcs=wcs_det)
        else:
            xap = SkyCircularAnnulus(center, r0, rx)
            photo = aperture_photometry(qhdu[0].data, xap, wcs=wcs)
            if (doMask):
                masked = aperture_photometry(detmask.data, xap, wcs=wcs_det)
        #
        ap_area = xap.to_pixel(wcs).area
        good_area = ap_area
        if (doMask):
            good_area = masked['aperture_sum'][0]
        # compare the two annuli areas: with and without bad pixels
        if (verbose):
            print(
                f"Annulus: {r0:.2f},{rx:.2f},geometric area: {ap_area:.1f} pixels,non-masked area {good_area:.1f} pixels, ratio: {ap_area / good_area:.2f}")
        # taking into account the masked pixels
        if (good_area == 0.0):
            counts.append(float('nan'))
            counts_err.append(float('nan'))
        else:
            counts.append(photo['aperture_sum'][0] / good_area)
            counts_err.append(np.sqrt(photo['aperture_sum'][0]) / good_area)

        j += 1
    #
    # convert the results in numpy arrays
    #
    rmid = np.array(rmid)
    counts = np.array(counts)
    counts_err = np.array(counts_err)
    #
    # convert per pixel to per arcsec^2
    pix_area = utils.proj_plane_pixel_area(wcs) * 3600.0 * 3600.0  # in arcsec^2
    counts = counts / pix_area
    counts_err = counts_err / pix_area
    #
    if (plot):
        fig, ax = plt.subplots(figsize=(10, 8))
        ax.errorbar(rmid, counts, xerr=rstep.value / 2.0, yerr=counts_err)
        ax.set_xscale('linear')
        ax.set_yscale('log')
        ax.set_xlabel('Radial distance (arcsec)')
        ax.set_ylabel(r'Counts/arcsec$^2$')
        ax.grid()
        ax.set_title(f"Radial profile");
    qhdu.close()
    if (doMask):
        det.close()
    return rmid, counts, counts_err
Beispiel #16
0
def get_counts(dirtarget,
               ra,
               dec,
               fil,
               aper_rad,
               ann_in_rad,
               ann_out_rad,
               name,
               date,
               set_rad=False,
               centroid_plot=False):
    """Generates background-substracted aperture sums for a source in an image.

    Defines source region as a 20x20 square centered at the input R.A. and dec.
    Source region is checked to ensure it is below the CCD saturation level,
    and lies entirely in the image. Centroiding is then performed to locate the
    central pixel of the source. An aperture and annulus are placed around this
    pixel and the background-subtracted aperture sum is calculated. All returns
    have size (#source(s) x #image(s)).

    Parameters
    ----------
    dirtarget : str
        Directory containing all bias, flat, and raw science images.
    ra : list
        List of string(s) of right ascension(s) of object(s) to be processed.
    dec : list
        List of string(s) of declination(s) of object(s) to be processed.
    fil : str
        Name of filter used for images which are currently being processed.
    aper_rad : float
        User-specified aperture radius in arcseconds.
    ann_in_rad : float
        User-specified annulus inner radius in arcseconds.
    ann_out_rad : float
        User-specified annulus outer radius in arcseconds.
    name : str
        Object type that get_counts is being ran on (e.g. target, comp, check).
    date : str
        Date of observation.
    set_rad : Boolean
        Determine whether user would like to use default aperture/annulus radii
        or specify their own.
    centroid_plot : Boolean
        Whether or not to plot centroid shifts for object.

    Returns
    -------
    aper_sum : numpy.ndarray
        Array of floats corresponding to aperture sums of each source.
    err : numpy.ndarray
        Array of floats corresponding to uncertainty of each aperture sum.
    date_obs : numpy.ndarray
        Array of floats corresponding to Julian Date of each image.
    altitudes : numpy.ndarray
        Array of floats corresponding to the altitude of each image.
    saturated : list
        List of list(s) containing the file path of any image whose source
        meets or exceeds the expected saturation level.
    exptimes : numpy.ndarray
        Array of floats corresponding to exposure time of each image.
    init_coords : numpy.ndarray
        Array of strings corresponding to the pixel coordinates (x,y) of the
        R.A. and dec. of the image's source, according to its WCS solution.
    cent_coords : numpy.ndarray
        Array of strings corresponding to the central pixel coordinates (x,y)
        of the centroided aperture. If the centroid routine failed, the string
        'init' is returned for that image.
    image_num : numpy.ndarray
        Array of integers containing the number of each image in dirtarget.
    sat_qual : numpy.ndarray
        Data quality mask that contains 0s for images that do not have a
        saturated source and 1s for source that do.
    cent_qual : numpy.ndarray
        Data quality mask that contains 0s for images with successful aperture
        centroiding and 1s for images with failed centoiding or poor WCS
        solutions.
    """
    dirtarget_wcs = os.path.join(dirtarget, 'ISR_Images', fil, 'WCS')
    files = sorted(glob.glob(os.path.join(dirtarget_wcs, '*.fits')))
    size_files = len(files)
    size_sources = len(ra)

    # Initialize output arrays.
    # Dimensions: #sources x #(images in dirtarget)
    aper_sum = np.empty([size_sources, size_files], dtype=float)
    aper_sum[:][:] = np.nan
    err = np.empty([size_sources, size_files], dtype=float)
    err[:][:] = np.nan
    date_obs = np.empty([size_sources, size_files], dtype=float)
    date_obs[:][:] = np.nan
    altitudes = np.empty([size_sources, size_files], dtype=float)
    altitudes[:][:] = np.nan
    saturated = []
    exptimes = np.empty([size_sources, size_files], dtype=float)
    exptimes[:][:] = np.nan
    init_coords = np.empty([size_sources, size_files], dtype=object)
    init_coords[:][:] = 'init'
    cent_coords = np.empty([size_sources, size_files], dtype=object)
    cent_coords[:][:] = 'init'
    image_num = np.empty([size_sources, size_files], dtype=object)
    image_num[:][:] = 'init'
    pix_radius = np.empty(size_sources, dtype=float)
    pix_radius[:] = np.nan
    image_arr = np.empty([size_sources, size_files], dtype=float)
    image_arr[:][:] = np.nan
    sat_qual = np.empty([size_sources, size_files], dtype=int)
    sat_qual[:][:] = 0
    cent_qual = np.empty([size_sources, size_files], dtype=int)
    cent_qual[:][:] = 0

    for i, (ra_i, dec_i) in enumerate(zip(ra, dec)):
        print('\nProcessing {} star ({})...'.format(name, fil))

        im = None
        p1 = None
        p2 = None
        circ = None
        fig = None
        ax = None
        pix_radius = None

        saturated_i = []

        # Initialize nine evenly-spaced indices to plot a centroiding summary.
        cent_ind = np.linspace(0, size_files - 1, 9).astype(int)
        if centroid_plot:
            fig, ax = plt.subplots(nrows=3, ncols=3, figsize=(10, 8))
            ax = ax.flatten()
            for k in range(0, 9):
                ax[k].set_title('Image {}'.format(cent_ind[k]), size=10)
                for l in (ax[k].get_xticklabels() + ax[k].get_yticklabels()):
                    l.set_fontsize(8)

        # fig_anim, ax_anim = plt.subplots(nrows=1, ncols=1, figsize=(10,8))
        # im_anim = plt.imshow()
        # def animate(i):
        for j, item in enumerate(files):
            o_file = os.path.join(dirtarget_wcs, item)
            hdulist = fits.open(o_file)
            header = hdulist[0].header
            data = hdulist[0].data

            im_str = str(o_file)
            im_n = im_str[-10:-7]
            try:
                int(im_n)
            except ValueError:
                im_n = j

            image_num[i][j] = im_n

            # Read output information from header of image being processed.
            exptimes[i][j] = float(header['EXPTIME'])
            date_j = header['DATE-OBS']
            t = Time(date_j)
            time = t.jd
            date_obs[i][j] = float(time)
            altitudes[i][j] = float(header['OBJCTALT'])

            # Check if WCS solution was successful.
            if header['WCSMATCH'] < 10:
                print('\nLess than 10 stars matched in WCS calculation.')
                cent_qual[i][j] = 1
                continue

            # Find pixel location of R.A. and dec. according to WCS solution
            w = WCS(header)
            coords = SkyCoord(ra_i, dec_i, unit=(u.hourangle, u.deg))
            px_dec, py_dec = w.wcs_world2pix(coords.ra.deg, coords.dec.deg, 1)
            px, py = int(px_dec), int(py_dec)
            init_coords_pix = (px, py)
            init_coords[i][j] = ','.join(map(str, init_coords_pix))

            # Define source region as a 20x20 square centered at (px,py)
            star = data[(py - 19):(py + 21), (px - 19):(px + 21)]

            # Check that region lies entirely within image.
            if ((py - 19) < 0) or ((py + 21) > 2084):
                print('\n{} star not entirely in the image for'.format(name) +
                      ' image number {}'.format(im_n))
                cent_qual[i][j] = 1
                continue
            if ((px - 19) < 0) or ((px + 21) > 3072):
                print('\n{} star not entirely in the image for'.format(name) +
                      ' image number {}'.format(im_n))
                cent_qual[i][j] = 1
                continue

            star_flat = star.reshape(1, len(star) * len(star[0]))

            # Check that source does not exceed the expected saturation level.
            max_pix = int(np.amax(star_flat))
            if max_pix >= header['SATLEVEL']:
                print('\n{} star met or exceeded saturation '.format(name) +
                      'level for image number {}.'.format(im_n))
                print('\nSaturation value: {}'.format(header['SATLEVEL']))
                print('\nMax aperture value: {}'.format(max_pix))
                saturated_i.append(item)
                sat_qual[i][j] = 1
                continue

            # Peform aperture centroiding for the source.
            # If centroiding failed, then move onto the next image.
            FWHM = 4
            try:
                mean, median, std = sigma_clipped_stats(star, sigma=3.0)
                daofind = DAOStarFinder(fwhm=FWHM, threshold=5. * std)
                sources = daofind(star - median)
                px_cent = np.average(sources['xcentroid'])
                py_cent = np.average(sources['ycentroid'])
            except TypeError:
                print('\nCentroiding failed for image {}.'.format(im_n))
                cent_qual[i][j] = 1
                continue

            # Return centroided pixel coordinates.
            x_cent = int(px - 19 + px_cent)
            y_cent = int(py - 19 + py_cent)

            cent_coords_pix = (x_cent, y_cent)
            cent_coords[i][j] = ','.join(map(str, cent_coords_pix))

            cent_equa = SkyCoord.from_pixel(x_cent, y_cent, w)

            # Define aperture and annulus radii.
            radius = None
            r_in = None
            r_out = None
            if set_rad:
                radius = float(aper_rad) * u.arcsec
                r_in = float(ann_in_rad) * u.arcsec
                r_out = float(ann_out_rad) * u.arcsec

            else:
                radius = 4 * u.arcsec
                r_in = 25 * u.arcsec
                r_out = 27 * u.arcsec

            # Create SkyCircularAperture and SkyCircularAnnulus objects
            # centered at the position of the star whose counts are being
            # summed.
            aperture = SkyCircularAperture(cent_equa, radius)
            annulus = SkyCircularAnnulus(cent_equa, r_in=r_in, r_out=r_out)

            apers = (aperture, annulus)

            secpix1 = abs(hdulist[0].header['SECPIX1'])

            # Determine the area of the aperture and annulus using the
            # arcseconds per pixel in the horizontal dimension header keyword.
            aper_area = np.pi * (radius / secpix1)**2
            area_out = np.pi * (r_out / secpix1)**2
            area_in = np.pi * (r_in / secpix1)**2
            annulus_area = area_out - area_in

            pix_radius = radius.value / secpix1

            # Call aperture_photometry function in order to sum all of the
            # counts in both the aperture and annulus for item.
            phot_table = aperture_photometry(hdulist, apers)

            # Remove the background level from the aperture sum.
            bkg_mean = phot_table['aperture_sum_1'] / annulus_area
            bkg_sum = bkg_mean * aper_area
            final_sum = phot_table['aperture_sum_0'] - bkg_sum
            phot_table['residual_aperture_sum'] = final_sum

            # Determine the error in the aperture sum and background level.
            # source_err = np.sqrt(phot_table['residual_aperture_sum'])
            source = phot_table['residual_aperture_sum']

            aper_sum[i][j] = phot_table['residual_aperture_sum'][0]
            err[i][j] = np.sqrt(source + bkg_sum)

            j_plot = np.where(cent_ind == j)[0]
            if centroid_plot:
                if j in cent_ind:
                    j_plot = j_plot[0]
                    p1 = ax[j_plot].scatter([px + 1], [py + 1],
                                            c="thistle",
                                            label="Original",
                                            edgecolors='mistyrose')
                    p2 = ax[j_plot].scatter([x_cent + 1], [y_cent + 1],
                                            c="rebeccapurple",
                                            label="Corrected",
                                            edgecolors='mistyrose')
                    im = ax[j_plot].imshow(star,
                                           extent=(px - 19, px + 21, py - 19,
                                                   py + 21),
                                           cmap='magma',
                                           origin='lower')
                    ax[j_plot].set_title('Image {}'.format(im_n), size=10)
                    circ = Circle((x_cent + 1, y_cent + 1),
                                  radius.value / secpix1,
                                  fill=False,
                                  label='Aperture',
                                  ls='-',
                                  color='mistyrose')
                    ax[j_plot].add_patch(circ)
                    for label in (ax[j_plot].get_xticklabels() +
                                  ax[j_plot].get_yticklabels()):
                        label.set_fontsize(8)

            hdulist.close()
            del data

        saturated.append(saturated_i)

        if centroid_plot:
            fig.subplots_adjust(right=0.8)
            cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
            cb = fig.colorbar(im, cax=cbar_ax)
            plt.setp(cb.ax.get_yticklabels(), fontsize=8)

            plt.figlegend([p1, p2, circ],
                          ['Original', 'Corrected', 'Aperture'],
                          fontsize=14)
            fig.suptitle('Aperture Centroiding on {}, {}'.format(ra_i, dec_i),
                         fontsize=16)
            fig.text(0.5, 0.04, 'x [pixel]', ha='center')
            fig.text(0.04, 0.5, 'y [pixel]', va='center', rotation='vertical')
            if name == 'comp':
                out_file = os.path.join('centroid_{}{}_{}_{}.pdf'.format(
                    name, i + 1, date, fil))
            else:
                out_file = os.path.join('centroid_{}_{}_{}.pdf'.format(
                    name, date, fil))

            plt.savefig(
                os.path.join(dirtarget, 'ISR_Images', fil, 'WCS', 'output',
                             out_file))

    return aper_sum, err, date_obs, altitudes, saturated, exptimes, \
        init_coords, cent_coords, image_num, sat_qual, cent_qual
Beispiel #17
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,
Beispiel #18
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 #19
0
    data_masked = np.ma.masked_invalid(data)

    return wcs, data_masked


############################################################
# main program

### Draw different regions.

position = SkyCoord(dec=0.8309 * u.degree,
                    ra=204.9906 * u.degree,
                    frame='icrs')
apertures['center']['sky'] = SkyCircularAperture(position, r=3 * u.arcsec)
apertures['ring around center']['sky'] = SkyCircularAnnulus(position,
                                                            r_in=3 * u.arcsec,
                                                            r_out=7 * u.arcsec)
position = SkyCoord(dec=0.8349 * u.degree,
                    ra=204.9930 * u.degree,
                    frame='icrs')
apertures['northarm']['sky'] = SkyEllipticalAperture(position,
                                                     a=15 * u.arcsec,
                                                     b=7 * u.arcsec,
                                                     theta=340 * u.degree)
position = SkyCoord(dec=0.8275 * u.degree,
                    ra=204.9884 * u.degree,
                    frame='icrs')
apertures['southarm']['sky'] = SkyEllipticalAperture(position,
                                                     a=10 * u.arcsec,
                                                     b=5 * u.arcsec,
                                                     theta=340 * u.degree)
Beispiel #20
0
print(r_pix)

#sys.exit(0)

#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(position, r5, r6)
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)
    #    print(i,j1,radec_deg[j1],ra_hhmmss[j1],dec_ddmmss[j1])
    rmag[j1] = df_refstar['Rmag'][j2]
    rmag_err[j1] = df_refstar['Rmag_err'][j2]
    r_circle[j1] = df_refstar['R_circle_as'][j2]
    r_inner[j1] = df_refstar['R_inner_as'][j2]
    r_outer[j1] = df_refstar['R_outer_as'][j2]
    #    position= SkyCoord(ra_deg[j1],dec_deg[j1],unit=(u.hourangle,u.deg),frame='icrs')
    position = SkyCoord(ra_deg[j1], dec_deg[j1], unit=(u.deg), frame='icrs')
    #    print(position)
    r_circle_as = r_circle[j1] * u.arcsec
    #    print(r_circle_as)
    aperture[j1] = SkyCircularAperture(position, r=r_circle_as)
    #    print(aperture[j1])
    r_inner_as = r_inner[j1] * u.arcsec
    r_outer_as = r_outer[j1] * u.arcsec
    aper_annu[j1] = SkyCircularAnnulus(position, r_inner_as, r_outer_as)
    #    print(aper_annu[j1])
    #    print(aper_annu[j1].r_in)
    #    print(aper_annu[j1].r_out)

    #    refstarID[j1]=df_refstar['RefStarID'][j2]
    #    refstarRA_deg[j1]=df_refstar['RefStarRA_deg'][j2]
    #    refstarDEC_deg[j1]=df_refstar['RefStarDEC_deg'][j2]
    #    print(refstarID[j1])
    #    print(refstarRA_deg[j1]
    #    print(refstarDEC_deg[j1])

    j1 = j1 + 1

dx = 500
dy = dx
Beispiel #22
0
def show_cutout_with_slit(hdr,
                          data=None,
                          slit_ra=None,
                          slit_dec=None,
                          slit_shape='rectangular',
                          slit_width=0.2,
                          slit_length=3.3,
                          slit_angle=90,
                          slit_radius=0.2,
                          slit_rout=0.5,
                          cmap='Greys_r',
                          plotname='',
                          **kwargs):
    """Show a cutout image with the slit(s) superimposed.

    Parameters
    ----------
    hdr : dict
        Cutout image header.

    data : ndarray or `None`, optional
        Cutout image data. If not given, data is not shown.

    slit_ra, slit_dec : float or array or `None`, optional
        Slit RA and DEC in degrees. Default is to use object position
        from image header. If an array is given, each pair of RA and
        DEC becomes a slit.

    slit_shape : {'annulus', 'circular', 'rectangular'}, optional
        Shape of the slit (circular or rectangular).
        Default is rectangular.

    slit_width, slit_length : float, optional
        Rectangular slit width and length in arcseconds.
        Defaults are some fudge values.

    slit_angle : float, optional
        Rectangular slit angle in degrees for the display.
        Default is vertical.

    slit_radius : float, optional
        Radius of a circular or annulus slit in arcseconds.
        For annulus, this is the inner radius.
        Default is some fudge value.

    slit_rout : float, optional
        Outer radius of an annulus slit in arcseconds.
        Default is some fudge value.

    cmap : str or obj, optional
        Matplotlib color map for image display. Default is grayscale.

    plotname : str, optional
        Filename to save plot as. If not given, it is not saved.

    kwargs : dict, optional
        Keyword argument(s) for the aperture overlay.
        If ``ax`` is given, it will also be used for image display.

    See Also
    --------
    make_cutouts

    """
    # Optional dependencies...
    import matplotlib.pyplot as plt
    from photutils import (SkyCircularAnnulus, SkyCircularAperture,
                           SkyRectangularAperture)

    if slit_ra is None:
        slit_ra = hdr['OBJ_RA']
    if slit_dec is None:
        slit_dec = hdr['OBJ_DEC']

    position = SkyCoord(slit_ra, slit_dec, unit='deg')

    if slit_shape == 'circular':
        slit_radius = u.Quantity(slit_radius, u.arcsec)
        aper = SkyCircularAperture(position, slit_radius)

    elif slit_shape == 'annulus':
        slit_rin = u.Quantity(slit_radius, u.arcsec)
        slit_rout = u.Quantity(slit_rout, u.arcsec)
        aper = SkyCircularAnnulus(position, slit_rin, slit_rout)

    else:  # rectangular
        slit_width = u.Quantity(slit_width, u.arcsec)
        slit_length = u.Quantity(slit_length, u.arcsec)
        slit_angle = u.Quantity(slit_angle, u.degree)
        aper = SkyRectangularAperture(position,
                                      slit_width,
                                      slit_length,
                                      theta=slit_angle)

    wcs = WCS(hdr)
    aper_pix = aper.to_pixel(wcs)
    ax = kwargs.get('ax', plt)

    if data is not None:
        ax.imshow(data, cmap=cmap, origin='lower')

    aper_pix.plot(**kwargs)

    if plotname:
        ax.savefig(plotname)
    aperture_pix = aperture.to_pixel(wcs)
    #    print(aperture_pix)
    r_pix = aperture_pix.r
    print('r_pix =', r_pix)
    #    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)
Beispiel #24
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)