示例#1
0
def first_cc_val_neg(param, *args):

    center_x, center_y = param
    data = args[0]
    radius_size = args[1]
    ones = np.array([[1] * 600] * 600)

    center_ap = CircularAperture([center_x, center_y], radius_size)
    center_area = center_ap.area
    center_mask = center_ap.to_mask(method='exact')
    center_data = center_mask.multiply(data)
    center_weights = center_mask.multiply(ones)
    center_std = twoD_weighted_std(center_data, center_weights)
    center_val = (np.sum(center_data)) / center_area + 5 * center_std

    first_ap = CircularAnnulus([center_x, center_y],
                               r_in=radius_size,
                               r_out=2 * radius_size)
    first_area = first_ap.area
    first_mask = first_ap.to_mask(method='exact')
    first_data = first_mask.multiply(data)
    first_weights = first_mask.multiply(ones)
    first_std = twoD_weighted_std(first_data, first_weights)
    first_val = (np.sum(first_data)) / first_area + 5 * first_std

    result = (-2.5 * math.log(first_val / center_val, 10))

    return -1 * (result)
def _filter_images(data, hmin):
    """Performs filtering/convolution on images for source finding"""
    #Laziest way to get a circle mask
    fp = CircularAperture((0, 0), r=hmin).to_mask().data > .1
    fp = fp.astype(bool)

    # Apply maximum filter, flux filter
    filt_image = maximum_filter(data, footprint=fp, mode='constant', cval=0)
    origins = product([0, -1], [0, -1])
    max_4sum = np.amax([_conv_origin(data, o) for o in origins], axis=0)
    return (filt_image, max_4sum)
    def _setup_cutout(self, data):
        """Cuts out the aperture and defines slice objects.
        General setup procedure.
        """
        self.ap = CircularAperture((self.x, self.y), r=self.r)
        mask = self.ap.to_mask()[0]
        self.sy = mask.bbox.slices[0]
        self.sx = mask.bbox.slices[1]
        self.cutout = mask.cutout(data, fill_value=np.nan)

        if self.cutout is None:
            self.is_empty = True
示例#4
0
def plotTestImage(imageArray):
    interval = ZScaleInterval()
    limits = interval.get_limits(imageArray)
    sources = locateStarsInImage(imageArray)
    positions = np.transpose((sources['xcentroid'], sources['ycentroid']))
    apertures = CircularAperture(positions, r=4.)
    norm = ImageNormalize(stretch=SqrtStretch())
    plt.imshow(imageArray,
               cmap='Greys',
               origin='lower',
               norm=norm,
               interpolation='nearest',
               vmin=limits[0],
               vmax=limits[1])
    apertures.plot(color='red', lw=1.5, alpha=0.5)
    plt.show()
def get_contrast_and_SN(res_fake, res_real, positions, fwhm_for_snr, fwhm_flux,
                        r_aperture, r_in_annulus, r_out_annulus):
    '''
    Args:
        res_fake : a 2D np.array. The path of repository where the files are.
        res_real : a 2D np.array. The path of another repository where the files are, for calculating snr.
        positions : a list of tuple (x,y). The coordinates of companions.
        fwhm : a float. fwhm's diameter.
        fwhm_flux : a float. The flux of fwhm.
    Return:
        contrast : a np.array, 1 dimension. Store the list of each companion's flux.
        SN : a np.array, 1 dimension. Store the list of each companion's Signal to Noise ratio.
    '''

    aperture = CircularAperture(positions, r=r_aperture)
    annulus = CircularAnnulus(positions,
                              r_in=r_in_annulus,
                              r_out=r_out_annulus)

    # contrast
    flux_companion = aperture_photometry(res_fake, [aperture, annulus])
    flux_companion['aperture_sum_0', 'aperture_sum_1'].info.format = '%.8g'
    flux = flux_companion['aperture_sum_0']
    contrast = (flux_companion['aperture_sum_0']) / fwhm_flux

    # SN
    SN = vip.metrics.snr(array=res_fake,
                         source_xy=positions,
                         fwhm=fwhm_for_snr,
                         plot=False,
                         array2=res_real,
                         use2alone=True)

    return contrast.data[0], SN, flux.data[0]
示例#6
0
def redoAperturePhotometry(catalog, imagedata, aperture, annulus_inner,
                           annulus_outer):
    """ Recalculate the FLUX column off a fits / BANZAI CAT extension based on operature photometry. """
    _logger.info("redoing aperture photometry")
    positions = [(catalog['x'][ii], catalog['y'][ii])
                 for ii in range(len(catalog['x']))]

    apertures = CircularAperture(positions, r=aperture)
    sky_apertures = CircularAnnulus(positions,
                                    r_in=annulus_inner,
                                    r_out=annulus_outer)
    sky_apertures_masks = sky_apertures.to_mask(method='center')
    bkg_median = []
    for mask in sky_apertures_masks:
        annulus_data = mask.multiply(imagedata)
        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)

    phottable = aperture_photometry(imagedata, [apertures, sky_apertures])

    # plt.plot (phottable['aperture_sum_1'] / sky_apertures.area, phottable['aperture_sum_1'] / sky_apertures.area - bkg_median,'.')
    # plt.savefig ('sky.png')

    newflux = phottable['aperture_sum_0'] - bkg_median * apertures.area

    # oldmag = -2.5 * np.log10(catalog['FLUX'])
    # newmag = -2.5 * np.log10 (newflux)
    # _logger.info ( newmag - oldmag)
    # plt.plot (newmag, newmag - oldmag, '.')
    # plt.savefig("Comparison.png")

    catalog['FLUX'] = newflux
示例#7
0
def get_one_contrast_and_SN(data, positions, fwhm, fwhm_flux):
    '''
    Args:
        path : a string. The path of repository where the files are.
        positions : a list of tuple (x,y). The coordinates of companions.
    Return:
        flux : a np.array, 1 dimension. Store the list of each companion's flux.
        SN : a np.array, 1 dimension. Store the list of each companion's Signal to Noise ratio.
    '''

    # flux
    aperture = CircularAperture(positions, r=2)
    annulus = CircularAnnulus(positions, r_in=4, r_out=6)

    # flux
    flux_companion = aperture_photometry(data, [aperture, annulus])
    flux_companion['aperture_sum_0', 'aperture_sum_1'].info.format = '%.8g'
    flux = (flux_companion['aperture_sum_0'] / aperture.area) / fwhm_flux

    # SN
    ds9 = vip.Ds9Window()
    ds9.display(data)
    SN = vip.metrics.snr(data, source_xy=positions[0], fwhm=fwhm, plot=True)

    return flux[0], SN
示例#8
0
def allreg_to_aperture(region):
    """Convert region object to aperture object."""

    region_type = type(region).__name__
    if "Pixel" in region_type:
        source_center = (region.center.x, region.center.y)
        if region_type == 'CirclePixelRegion':
            return CircularAperture(source_center, r=region.radius)
        elif region_type == "CircleAnnulusPixelRegion":
            return CircularAnnulus(source_center,
                                   r_in=region.inner_radius,
                                   r_out=region.outer_radius)
        elif region_type == "EllipsePixelRegion":
            # to be tested
            return EllipticalAperture(source_center,
                                      a=region.width,
                                      b=region.height,
                                      angle=region.angle)
    elif "Sky" in region_type:
        center = region.center.fk5
        if region_type == "CircleSkyRegion":
            return SkyCircularAperture(center, r=region.radius)
        elif region_type == "EllipseSkyRegion":
            return SkyEllipticalAperture(center,
                                         a=region.width / 2,
                                         b=region.height / 2,
                                         angle=region.angle)
        elif region_type == "CircleAnnulusSkyRegion":
            return SkyCircularAnnulus(center,
                                      r_in=region.inner_radius,
                                      r_out=region.outer_radius)
    else:
        print("Error region not implemented")
        return None
示例#9
0
    def set_aperture_properties(self):
        """
        Calculate the aperture photometry.

        The values are set as dynamic attributes.
        """
        apertures = [
            CircularAperture(self._xypos_finite, radius)
            for radius in self.aperture_params['aperture_radii']
        ]
        aper_phot = aperture_photometry(self.model.data,
                                        apertures,
                                        error=self.model.err)

        for i, aperture in enumerate(apertures):
            flux_col = f'aperture_sum_{i}'
            flux_err_col = f'aperture_sum_err_{i}'

            # subtract the local background measured in the annulus
            aper_phot[flux_col] -= (self.aper_bkg_flux * aperture.area)

            flux = aper_phot[flux_col]
            flux_err = aper_phot[flux_err_col]
            abmag, abmag_err = self.convert_flux_to_abmag(flux, flux_err)
            vegamag = abmag - self.abvega_offset
            vegamag_err = abmag_err

            idx0 = 2 * i
            idx1 = (2 * i) + 1
            setattr(self, self.aperture_flux_colnames[idx0], flux)
            setattr(self, self.aperture_flux_colnames[idx1], flux_err)
            setattr(self, self.aperture_abmag_colnames[idx0], abmag)
            setattr(self, self.aperture_abmag_colnames[idx1], abmag_err)
            setattr(self, self.aperture_vegamag_colnames[idx0], vegamag)
            setattr(self, self.aperture_vegamag_colnames[idx1], vegamag_err)
def create_dao_like_sourcelists(fitsfile,
                                sl_filename,
                                sources,
                                aper_radius=4.,
                                make_region_file=False):
    """Make DAOphot-like sourcelists

    Parameters
    ----------
    fitsfile : string
        Name of the drizzle-combined filter product to used to generate photometric sourcelists.


    sl_filename : string
        Name of the sourcelist file that will be generated by this subroutine

    sources : astropy table
        Table containing x, y coordinates of identified sources

    aper_radius : float
        Aperture radius (in pixels) used for photometry. Default value = 4.

    make_region_file : Boolean
        Generate ds9-compatible region file(s) along with the sourcelist? Default value = False

    Returns
    -------
    Nothing.
    """
    # Open and background subtract image
    hdulist = fits.open(fitsfile)
    image = hdulist['SCI'].data
    image -= np.nanmedian(image)

    # Aperture Photometry
    positions = (sources['xcentroid'], sources['ycentroid'])
    apertures = CircularAperture(positions, r=aper_radius)
    phot_table = aperture_photometry(image, apertures)

    for col in phot_table.colnames:
        phot_table[col].info.format = '%.8g'  # for consistent table output
    hdulist.close()

    # Write out sourcelist
    tbl_length = len(phot_table)
    phot_table.write(sl_filename, format="ascii.ecsv")
    log.info("Created sourcelist file '{}' with {} sources".format(
        sl_filename, tbl_length))

    # Write out ds9-compatable .reg file
    if make_region_file:
        reg_filename = sl_filename.replace(".ecsv", ".reg")
        out_table = phot_table.copy()
        out_table['xcenter'].data = out_table['xcenter'].data + np.float64(1.0)
        out_table['ycenter'].data = out_table['ycenter'].data + np.float64(1.0)
        out_table.remove_column('id')
        out_table.write(reg_filename, format="ascii")
        log.info("Created region file '{}' with {} sources".format(
            reg_filename, tbl_length))
示例#11
0
def get_contrast_and_SN(path, positions, fwhm, fwhm_flux, path_real):
    '''
    Args:
        path : a string. The path of repository where the files are.
        positions : a list of tuple (x,y). The coordinates of companions.
        fwhm : a float. fwhm's diameter.
        fwhm_flux : a float. The flux of fwhm.
        path_real : a string. The path of another repository where the files are, for calculating snr.
    Return:
        contrast : a np.array, 1 dimension. Store the list of each companion's flux.
        SN : a np.array, 1 dimension. Store the list of each companion's Signal to Noise ratio.
    '''
    files = os.listdir(path)
    files.sort()
    
    files_real = os.listdir(path_real)
    files_real.sort()
    l = len(files)
    

    flux = np.zeros(l)
    # contrast
    contrast = np.zeros(l)
    aperture = CircularAperture(positions, r=2)
    annulus = CircularAnnulus(positions, r_in=4, r_out=6)
 
    # SN
    SN = np.zeros(l)

    for i in range(l):
        file = path+'/'+files[i]
        print("file",i,"=", file)
        data = vip.fits.open_fits(file)
        
        # contrast
        flux_companion = aperture_photometry(data, [aperture, annulus])
        flux_companion['aperture_sum_0','aperture_sum_1'].info.format = '%.8g'
        #bkg_mean = flux_companion['aperture_sum_1']/annulus.area
        #bkg_sum_in_companion = bkg_mean * aperture.area
        flux[i] = flux_companion['aperture_sum_0'] 
        contrast[i] = (flux_companion['aperture_sum_0']/aperture.area)/fwhm_flux

        # SN
        lets_plot = False
        if i==2:
            lets_plot = True
            #ds9.display(data)
        file_real = path_real+'/'+files_real[i]
        print("array2 at ",i," =", file_real)
        data2 = vip.fits.open_fits(file_real)
        SN[i] = vip.metrics.snr(array=data, source_xy=positions, fwhm=fwhm, plot=lets_plot, array2 = data2, use2alone=True)
        
    return contrast, SN
示例#12
0
def aper_phot(image, mask, xc, yc, radii, rsky, debug):

    positions = [(xc, yc)]

    # Define apertures
    apertures = [CircularAperture(positions, r=r) for r in radii]
    if (debug == 1):
        #        print("line ", lineno()," apertures  : ", apertures)
        print("line ", lineno(), " aper_phot: positions: ", positions)
        print("line ", lineno(), " aper_phot: sky aperture ", rsky)
#        for rr in range(0,len(radii)):
#            print("line ", lineno(), " apertures[rr].r, apertures[rr].area :", apertures[rr].r, apertures[rr].area )

# Background, masking bad pixels
    annulus_aperture = CircularAnnulus(positions, r_in=rsky[0], r_out=rsky[1])
    annulus_masks = annulus_aperture.to_mask(method='center')
    bkg_median = []
    for anm in annulus_masks:
        annulus_data = anm.multiply(image)
        annulus_data_1d = annulus_data[anm.data > 0]
        if (debug == 1):
            print("line ", lineno(), " aper_phot: annulus_data_1d.shape ",
                  annulus_data_1d.shape)

        # Remove NaNs, Infs
        annulus_data_1d = annulus_data_1d[np.isfinite(annulus_data_1d)]
        _, median_sigclip, _ = sigma_clipped_stats(annulus_data_1d)
        bkg_median.append(median_sigclip)
        if (debug == 1):
            print("line ", lineno(), " aper_phot: annulus_data_1d.shape ",
                  annulus_data_1d.shape)
            print("line ", lineno(), " aper_phot: median sigclip",
                  median_sigclip)
    if (debug == 1):
        print("line ", lineno(), " aper_phot: bkg_median ", bkg_median)

    phot_table = aperture_photometry(image, apertures, mask=mask)
    #
    junk = []
    area_list = []
    n = -1
    for index in phot_table.colnames:
        if ('aperture_sum' in index):
            n = n + 1
            array = phot_table[index].data[0]
            flux = array.tolist()
            bkg = apertures[n].area * bkg_median[0]
            junk.append(flux - bkg)
            area_list.append(apertures[n].area)
    apflux = np.array(junk)
    area = np.array(area_list)
    #    (diff, encircled)  = differential(apflux,area,True,False)
    return apflux, area
示例#13
0
 def compute_circular_aperture(self, centre, radius, flux_return=False,
                               plot=False):
     from photutils.aperture import CircularAperture#, aperture_photometry
     aperture = CircularAperture(centre, r=radius)
     aperture_mask = aperture.to_mask()
     aperture_mask = np.array(
         aperture_mask.to_image(self.wcs.celestial.array_shape), dtype=bool)
     
     if flux_return:
         integrated_flux = np.nansum(self.flux[:, aperture_mask], axis=1)
         integrated_no_cov = np.nansum(self.flux_error[:, aperture_mask]**2, axis=1)
         ## Accounting for covariance errors
         if aperture_mask[aperture_mask].size<100:
             integrated_flux_cov = integrated_no_cov*(
                 1+1.62*np.log10(aperture_mask[aperture_mask].size))
             integrated_flux_err = np.sqrt(integrated_flux_cov)
         else:
             integrated_flux_cov = integrated_no_cov*4.2
             integrated_flux_err = np.sqrt(integrated_flux_cov)
     else:
         integrated_flux = None
         integrated_flux_err = None
     if plot:
         fig = plt.figure()
         ax = fig.add_subplot(111)
         ax.imshow(self.flux[self.wl.size//2, :, :], cmap='gist_earth_r')            
         aperture.plot(lw=1, color='r')
         ax.annotate(r'$R_e={:4.3}~(Kpc)$'.format(self.eff_radius_physical),
                     xy=(.9,.95), xycoords='axes fraction', va='top', ha='right')            
         ax.annotate(r'$R_e={:4.3}~(arcsec)$'.format(self.eff_radius),
                     xy=(.9,.9), xycoords='axes fraction', va='top', ha='right')
         aperture.plot(lw=1, color='r')
         ax.annotate(r'$R_e={:4.3}~(pix)$'.format(self.eff_radius_pix),
                     xy=(.9,.85), xycoords='axes fraction', va='top', ha='right')
         ax.annotate(r'$R_a={:4.3}~(pix)$'.format(radius),
                     xy=(.9,.80), xycoords='axes fraction', va='top', ha='right',
                     color='r')
         aperture.plot(lw=1, color='r')
         # plt.savefig('bpt_apertures/'+name_i+'.png')
         plt.show()
         plt.close()
         return aperture, aperture_mask, integrated_flux, integrated_flux_err, fig 
     else:           
         return aperture, aperture_mask, integrated_flux, integrated_flux_err    
示例#14
0
def compute_eff_radii(image, plot=False):
    max_pix_rad = np.min(image.shape) // 2
    radius = np.arange(3, max_pix_rad, 3)
    fake_image = np.zeros_like(image)
    fake_image[max_pix_rad // 2:(3 * max_pix_rad) // 2,
               max_pix_rad // 2:(3 * max_pix_rad) //
               2] = image[max_pix_rad // 2:(3 * max_pix_rad) // 2,
                          max_pix_rad // 2:(3 * max_pix_rad) // 2]
    com_x, com_y = centroid_2dg(fake_image)
    aperture_sum = []
    for rad_i in radius:
        aperture = CircularAperture((com_x, com_y), r=rad_i)
        phot_table = aperture_photometry(image, aperture)
        aperture_sum.append(phot_table['aperture_sum'].value)
    aperture_sum = np.array(aperture_sum).squeeze()
    norm_aperture_sum = aperture_sum / aperture_sum[-1]
    half_mass_rad = np.interp(0.5, norm_aperture_sum, radius)
    half_mass_aperture = CircularAperture((com_x, com_y), r=half_mass_rad)
    two_half_mass_aperture = CircularAperture((com_x, com_y),
                                              r=2 * half_mass_rad)
    half_mass_table = aperture_photometry(image, half_mass_aperture)
    two_half_mass_table = aperture_photometry(image, two_half_mass_aperture)
    if plot:
        fig = plt.figure()
        plt.imshow(np.log10(image))
        plt.colorbar(label='log(image)')
        plt.plot(com_x, com_y, '+', markersize=8, color='c')
        half_mass_aperture.plot(color='r', lw=2, label=r'Half mass rad')
        two_half_mass_aperture.plot(color='orange',
                                    lw=2,
                                    label=r'Two half mass rad')
        plt.annotate(
            'Tot mass={:.2}\nHalf mass={:.2}\nTwoHalf mass={:.2}'.format(
                float(aperture_sum[-1]),
                float(half_mass_table['aperture_sum'].value),
                float(two_half_mass_table['aperture_sum'].value)),
            xy=(.1, 1),
            xycoords='axes fraction',
            va='bottom')
        plt.legend()
        plt.close()
        return half_mass_aperture, two_half_mass_aperture, fig
    else:
        return half_mass_aperture, two_half_mass_aperture
def get_contrast_and_SN_only_real(res_real, positions, fwhm_for_snr, psf,
                                  r_aperture, r_in_annulus, r_out_annulus):
    '''
    Args:
        res_real : a 2D np.array. The path of another repository where the files are, for calculating snr.
        positions : a list of tuple (x,y). The coordinates of companions.
        psf : a 2D np.array. The image of flux.
        fwhm_flux : a float. The flux of fwhm.
        r_aperture, r_in_annulus, r_out_annulus : see args.
    Return:
        contrast : a np.array, 1 dimension. Store the list of each companion's flux.
        SN : a np.array, 1 dimension. Store the list of each companion's Signal to Noise ratio.
    '''

    aperture = CircularAperture(positions, r=r_aperture)
    annulus = CircularAnnulus(positions,
                              r_in=r_in_annulus,
                              r_out=r_out_annulus)

    # contrast
    flux_companion = aperture_photometry(res_real, [aperture, annulus])
    flux_companion['aperture_sum_0', 'aperture_sum_1'].info.format = '%.8g'
    flux = flux_companion['aperture_sum_0']

    x, y = psf.shape
    aperture_psf = CircularAperture((x // 2, y // 2), r=r_aperture)
    flux_psf = aperture_photometry(psf, aperture_psf)
    flux_psf['aperture_sum'].info.format = '%.8g'

    contrast = (flux_companion['aperture_sum_0']) / flux_psf['aperture_sum']

    # SN
    SN = vip.metrics.snr(array=res_real,
                         source_xy=positions,
                         fwhm=fwhm_for_snr,
                         plot=False)

    return contrast.data[0], SN, flux.data[0]
示例#16
0
def region_to_aperture(region, wcs=None):
    """Convert region object to photutils.aperture.aperture_photometry object. The wcs object is needed only if the input regions are in sky coordinates.
    Parameters
    ----------
    region: regions.Region
        Output of read_ds9 method or str
    wcs: astropy.wcs.WCS
        A world coordinate system if the region in sky coordinates IS needed to convert it to pixels.
    """

    if type(region) == str:
        region = read_ds9(region)[0]
    print(region)
    region_type = type(region).__name__
    if "Pixel" in region_type:
        source_center = (region.center.x, region.center.y)
        if region_type == 'CirclePixelRegion':
            return CircularAperture(source_center, r=region.radius)
        elif region_type == "CircleAnnulusPixelRegion":
            return CircularAnnulus(source_center,
                                   r_in=region.inner_radius,
                                   r_out=region.outer_radius)
        elif region_type == "EllipsePixelRegion":
            # to be tested
            return EllipticalAperture(source_center,
                                      a=region.width,
                                      b=region.height,
                                      theta=region.angle)
    elif "Sky" in region_type:
        if wcs is None:
            print("Error, cannot obtain aperture without a wcs.")
            return None
        center = region.center.fk5
        if region_type == "CircleSkyRegion":
            return SkyCircularAperture(center, r=region.radius).to_pixel(wcs)
        elif region_type == "CircleAnnulusSkyRegion":
            print("Region %s not implemented")
        elif region_type == "EllipseSkyRegion":
            return SkyEllipticalAperture(center,
                                         a=region.width,
                                         b=region.height,
                                         theta=region.angle).to_pixel(wcs)
        elif region_type == "CircleAnnulusSkyRegion":
            return SkyCircularAnnulus(center,
                                      r_in=region.inner_radius,
                                      r_out=region.outer_radius).to_pixel(wcs)
    else:
        print("Error region not implemented")
        return None
示例#17
0
def get_SN(path, positions, fwhm):
    '''
    Args:
        path : a string. The path of repository where the files are.
        positions : a list of tuple (x,y). The coordinates of companions.
    Return:
        flux : a np.array, 1 dimension. Store the list of each companion's flux.
        SN : a np.array, 1 dimension. Store the list of each companion's Signal to Noise ratio.
    '''
    files = os.listdir(path)
    files.sort()
    l = len(files)

    # flux
    flux = np.zeros(l)
    aperture = CircularAperture(positions, r=2)
    annulus = CircularAnnulus(positions, r_in=4, r_out=6)

    # SN
    SN = np.zeros(l)

    for i in range(l):
        file = path + '/' + files[i]
        print("file", i, "=", file)
        data = vip.fits.open_fits(file)

        # flux
        flux_companion = aperture_photometry(data, [aperture, annulus])
        flux_companion['aperture_sum_0', 'aperture_sum_1'].info.format = '%.8g'
        #bkg_mean = flux_companion['aperture_sum_1']/annulus.area
        #bkg_sum_in_companion = bkg_mean * aperture.area
        #flux[i] = flux_companion['aperture_sum_0'] - bkg_sum_in_companion
        flux[i] = (flux_companion['aperture_sum_0'] / aperture.area)

        # SN
        lets_plot = False
        if i == 2:
            lets_plot = True
            #ds9.display(data)
        SN[i] = vip.metrics.snr(data,
                                source_xy=positions[0],
                                fwhm=fwhm,
                                plot=lets_plot)

    return flux, SN
示例#18
0
def aper_phot_old(image, xc, yc, radii, plot_results,profile_png, mask=None,verbose=False):

    positions = [(xc, yc)]

    apertures = [CircularAperture(positions, r=r) for r in radii ]
    phot_table = aperture_photometry(image, apertures,mask=mask)
#
    junk = []
#    print(phot_table)
#    print(type(phot_table))
    for index  in phot_table.colnames:
        if('aperture_sum' in index):
            array = phot_table[index].data[0]
            temp  = array.tolist()
            junk.append(temp)
    values = np.array(junk)
    diff   = np.zeros(len(values))
    diff[0] = values[0]
    for ii in range(1,len(values)):
        diff[ii]= values[ii]-values[ii-1]
        if(verbose == True or verbose == 1):
            print(values[ii], diff[ii])

    if(verbose == True or verbose == 1):
        print("positions: " ,positions)
        print("Radii  :", radii)
        print("values :",values)

    if(plot_results == True) :
        fig = plt.figure(figsize=(10,8))
        plt.subplot(2, 1, 1)
        plt.plot(radii, values,'bo',markersize=4)
        plt.xlabel("radius (pixels)")
        plt.ylabel("totalintensity")

        plt.subplot(2, 1, 2)
        diff = diff/diff[0]
        plt.plot(radii, diff,'bo',markersize=4)
        plt.yscale("log")
        plt.xlabel("radius (pixels)")
        plt.ylabel("Normalised intensity")
        plt.savefig(profile_png,bbox_inches='tight')
        plt.show()
        return
示例#19
0
    def doapphot(self, apradlist, units='arcsec'):
        """ Measure the flux in one or more apertures.
        :param apradlist: float or array-like
           aperture radius or list of radii.  
        :param units: 'arcsec' or 'pixels'; 
           the units for the aperture radii in apradlist.
        """
        if not np.iterable(apradlist):
            apradlist = [apradlist]
        if units == 'arcsec':
            apradlist = [ap / self.pixscale for ap in apradlist]
        if self.skyvalperpix is None:
            self.get_sky_from_annulus()

        xy = [self.x_0, self.y_0]
        apertures = [CircularAperture(xy, r) for r in apradlist]
        phot_table = aperture_photometry(
            self.imdat, apertures, error=None, mask=None,
            method=u'exact', subpixels=5, unit=None, wcs=None)

        # Modify the output photometry table
        if 'aperture_sum' in phot_table.colnames:
            # if we had only a single aperture, then the aperture sum column
            # has no index number at the end. So we add it.
            phot_table.rename_column('aperture_sum', 'aperture_sum_0')
        for i in range(len(apertures)):
            # add a column for each aperture specifying the radius in arcsec
            colname = 'radius_arcsec_{:d}'.format(i)
            apradarcsec = apradlist[i] * self.pixscale
            apcol = Column(name=colname, data=[apradarcsec,])
            phot_table.add_column(apcol)

        self._photutils_output_dict['aperturephot'] = \
            MeasuredPhotometry('aperturephot', 'aperture')
        self._photutils_output_dict['aperturephot'].photresultstable = \
            phot_table
        self._photutils_output_dict['aperturephot'].get_flux_and_mag(
            self.zpt, self.camera, self.filter)
示例#20
0
        # 3. result of cADI
        data = origin_flux_companion(
            slice_frame(target_frames, len(target_frames[0, 0, 0]), scale),
            read_file(str(sys.argv[2]), "ROTATION"))
        data_bkg_mean = radial_data_mean(data[0])
        c = plt.imshow(data_bkg_mean, interpolation='nearest', origin='lower')
        plt.colorbar(c)
        plt.title('backgraound flux of target science')
        plt.show()

        #hdu = fits.PrimaryHDU(res_cADI)
        #hdu.writeto("./GJ_667C_origin_rotated.fits")
        positions = [(126.05284, 249.11)]
        #positions = [(143.06025, 166.01939)]
        aperture = CircularAperture(positions, r=2)
        annulus = CircularAnnulus(positions, r_in=4, r_out=6)

        #data[0][1:,1:] = data[0][1:,1:] - data_bkg_mean
        flux_companion = aperture_photometry(data[0], [aperture, annulus])
        bkg_mean = flux_companion['aperture_sum_1'] / annulus.area
        bkg_sum_in_companion = bkg_mean * aperture.area

        print(flux_companion)
        print("bkg_mean =", bkg_mean[0], "\naperture.area =", aperture.area,
              "\nannulus.area =", annulus.area)
        print("bkg_sum_in_companion =", bkg_sum_in_companion[0])
        flux_companion_origin = flux_companion[
            'aperture_sum_0'] - bkg_sum_in_companion
        print("flux companion origin =", flux_companion_origin[0])
示例#21
0
#%% find the sources
daofind = DAOStarFinder(fwhm=seeing, sky=median, threshold=5. * std)
sources = daofind.find_stars(imdata - median)

print('\nPrint source locations:')
sources['id', 'xcentroid',
        'ycentroid'].pprint()  #print out positions of sources
print('\n')

#%% perform aperture photometry
# extract source postions from table; transpose is needed for proper orientation
positions = np.transpose((sources['xcentroid'], sources['ycentroid']))
# define the aperture
r_a = 3 * seeing
apertures = CircularAperture(positions, r=r_a)
# define the annulus
r_in = r_a + 3
r_out = r_in + 15
annulus = CircularAnnulus(positions, r_in=r_in, r_out=r_out)

# plot image with apertures
y_or_n = input('Do you wish to display the image and appertures? ')
if (y_or_n[0] == 'y') or (y_or_n[0] == 'Y'):
    plt.figure(1)
    plt.clf()

    # label the sources
    mylabels = sources['id']
    for idx, txt in enumerate(mylabels):
        plt.annotate(txt, (positions[idx, 0], positions[idx, 1]))
示例#22
0
def tso_aperture_photometry(datamodel, xcenter, ycenter, radius, radius_inner,
                            radius_outer):
    """
    Create a photometric catalog for NIRCam TSO imaging observations.

    Parameters
    ----------
    datamodel : `CubeModel`
        The input `CubeModel` of a NIRCam TSO imaging observation.

    xcenter, ycenter : float
        The ``x`` and ``y`` center of the aperture.

    radius : float
        The radius (in pixels) of the circular aperture.

    radius_inner, radius_outer : float
        The inner and outer radii (in pixels) of the circular-annulus
        aperture, used for local background estimation.

    Returns
    -------
    catalog : `~astropy.table.QTable`
        An astropy QTable (Quantity Table) containing the source
        photometry.
    """

    if not isinstance(datamodel, CubeModel):
        raise ValueError('The input data model must be a CubeModel.')

    # For the SUB64P subarray with the WLP8 pupil, the circular aperture
    # extends beyond the image and the circular annulus does not have any
    # overlap with the image.  In that case, we simply sum all values
    # in the array and skip the background subtraction.
    sub64p_wlp8 = False
    if (datamodel.meta.instrument.pupil == 'WLP8'
            and datamodel.meta.subarray.name == 'SUB64P'):
        sub64p_wlp8 = True

    if not sub64p_wlp8:
        phot_aper = CircularAperture((xcenter, ycenter), r=radius)
        bkg_aper = CircularAnnulus((xcenter, ycenter),
                                   r_in=radius_inner,
                                   r_out=radius_outer)

    # convert the input data and errors from MJy/sr to Jy
    if datamodel.meta.bunit_data != 'MJy/sr':
        raise ValueError('data is expected to be in units of MJy/sr')
    factor = 1.e6 * datamodel.meta.photometry.pixelarea_steradians
    datamodel.data *= factor
    datamodel.err *= factor
    datamodel.meta.bunit_data = 'Jy'
    datamodel.meta.bunit_err = 'Jy'

    aperture_sum = []
    aperture_sum_err = []
    annulus_sum = []
    annulus_sum_err = []

    nimg = datamodel.data.shape[0]

    if sub64p_wlp8:
        info = ('Photometry measured as the sum of all values in the '
                'subarray.  No background subtraction was performed.')

        for i in np.arange(nimg):
            aperture_sum.append(np.sum(datamodel.data[i, :, :]))
            aperture_sum_err.append(np.sqrt(np.sum(datamodel.err[i, :, :]**2)))
    else:
        info = ('Photometry measured in a circular aperture of r={0} '
                'pixels.  Background calculated as the mean in a '
                'circular annulus with r_inner={1} pixels and '
                'r_outer={2} pixels.'.format(radius, radius_inner,
                                             radius_outer))
        for i in np.arange(nimg):
            aper_sum, aper_sum_err = phot_aper.do_photometry(
                datamodel.data[i, :, :], error=datamodel.err[i, :, :])
            ann_sum, ann_sum_err = bkg_aper.do_photometry(
                datamodel.data[i, :, :], error=datamodel.err[i, :, :])

            aperture_sum.append(aper_sum[0])
            aperture_sum_err.append(aper_sum_err[0])
            annulus_sum.append(ann_sum[0])
            annulus_sum_err.append(ann_sum_err[0])

    aperture_sum = np.array(aperture_sum)
    aperture_sum_err = np.array(aperture_sum_err)
    annulus_sum = np.array(annulus_sum)
    annulus_sum_err = np.array(annulus_sum_err)

    # construct metadata for output table
    meta = OrderedDict()
    meta['instrument'] = datamodel.meta.instrument.name
    meta['detector'] = datamodel.meta.instrument.detector
    meta['channel'] = datamodel.meta.instrument.channel
    meta['subarray'] = datamodel.meta.subarray.name
    meta['filter'] = datamodel.meta.instrument.filter
    meta['pupil'] = datamodel.meta.instrument.pupil
    meta['target_name'] = datamodel.meta.target.catalog_name
    meta['xcenter'] = xcenter
    meta['ycenter'] = ycenter
    ra_icrs, dec_icrs = datamodel.meta.wcs(xcenter, ycenter)
    meta['ra_icrs'] = ra_icrs
    meta['dec_icrs'] = dec_icrs
    meta['apertures'] = info

    # initialize the output table
    tbl = QTable(meta=meta)

    # check for the INT_TIMES table extension
    if hasattr(datamodel, 'int_times') and datamodel.int_times is not None:
        nrows = len(datamodel.int_times)
    else:
        nrows = 0
        log.warning("The INT_TIMES table in the input file is missing or "
                    "empty.")

    # load the INT_TIMES table data
    if nrows > 0:
        shape = datamodel.data.shape
        if len(shape) == 2:
            num_integ = 1
        else:  # len(shape) == 3
            num_integ = shape[0]
        int_start = datamodel.meta.exposure.integration_start
        if int_start is None:
            int_start = 1
            log.warning(f"INTSTART not found; assuming a value of {int_start}")

        # Columns of integration numbers & times of integration from the
        # INT_TIMES table.
        int_num = datamodel.int_times['integration_number']
        mid_utc = datamodel.int_times['int_mid_MJD_UTC']
        offset = int_start - int_num[0]  # both are one-indexed
        if offset < 0:
            log.warning("Range of integration numbers in science data extends "
                        "outside the range in INT_TIMES table.")
            log.warning("Can't use INT_TIMES table.")
            del int_num, mid_utc
            nrows = 0  # flag as bad
        else:
            log.debug("Times are from the INT_TIMES table")
            time_arr = mid_utc[offset:offset + num_integ]
            int_times = Time(time_arr, format='mjd', scale='utc')

    # compute integration time stamps on the fly
    if nrows == 0:
        log.debug("Times computed from EXPSTART and EFFINTTM")
        dt = datamodel.meta.exposure.integration_time
        n_dt = (datamodel.meta.exposure.integration_end -
                datamodel.meta.exposure.integration_start + 1)
        dt_arr = (np.arange(1, 1 + n_dt) * dt - (dt / 2.))
        int_dt = TimeDelta(dt_arr, format='sec')
        int_times = (Time(datamodel.meta.exposure.start_time, format='mjd') +
                     int_dt)

    # populate table columns
    unit = u.Unit(datamodel.meta.bunit_data)
    tbl['MJD'] = int_times.mjd
    tbl['aperture_sum'] = aperture_sum << unit
    tbl['aperture_sum_err'] = aperture_sum_err << unit

    if not sub64p_wlp8:
        tbl['annulus_sum'] = annulus_sum << unit
        tbl['annulus_sum_err'] = annulus_sum_err << unit

        annulus_mean = annulus_sum / bkg_aper.area
        annulus_mean_err = annulus_sum_err / bkg_aper.area
        aperture_bkg = annulus_mean * phot_aper.area
        aperture_bkg_err = annulus_mean_err * phot_aper.area

        tbl['annulus_mean'] = annulus_mean << unit
        tbl['annulus_mean_err'] = annulus_mean_err << unit

        tbl['aperture_bkg'] = aperture_bkg << unit
        tbl['aperture_bkg_err'] = aperture_bkg_err << unit

        net_aperture_sum = aperture_sum - aperture_bkg
        net_aperture_sum_err = np.sqrt(aperture_sum_err**2 +
                                       aperture_bkg_err**2)
        tbl['net_aperture_sum'] = net_aperture_sum << unit
        tbl['net_aperture_sum_err'] = net_aperture_sum_err << unit
    else:
        colnames = [
            'annulus_sum', 'annulus_sum_err', 'annulus_mean',
            'annulus_mean_err', 'aperture_bkg', 'aperture_bkg_err'
        ]
        for col in colnames:
            tbl[col] = np.full(nimg, np.nan)

        tbl['net_aperture_sum'] = aperture_sum << unit
        tbl['net_aperture_sum_err'] = aperture_sum_err << unit

    return tbl
示例#23
0
def ConCur(star_data,
           radius_size=1,
           center=None,
           background_method='astropy',
           find_hots=False,
           find_center=False):

    data = star_data.copy()

    background_mean, background_std = background_calc(data, background_method)

    x, y = np.indices((data.shape))

    if not center:
        center = np.array([(x.max() - x.min()) / 2.0,
                           (y.max() - y.min()) / 2.0])

    if find_hots == True:
        hots = hot_pixels(data, center, background_mean, background_std)

    if find_center == True:
        center_vals = find_best_center(data, radius_size, center)
        center = np.array([center_vals[0], center_vals[1]])

    radii = np.sqrt((x - center[0])**2 + (y - center[1])**2)
    radii = radii.astype(np.int)

    ones = np.array([[1] * len(data)] * len(data[0]))

    number_of_a = radii.max() / radius_size

    center_ap = CircularAperture([center[0], center[1]], radius_size)

    all_apers, all_apers_areas, all_masks = [center_ap], [center_ap.area], [
        center_ap.to_mask(method='exact')
    ]

    all_data, all_weights = [all_masks[0].multiply(data)
                             ], [all_masks[0].multiply(ones)]

    all_stds = [twoD_weighted_std(all_data[0], all_weights[0])]

    for j in range(int(number_of_a)):
        aper = CircularAnnulus([center[0], center[1]],
                               r_in=(j * radius_size + radius_size),
                               r_out=(j * radius_size + 2 * radius_size))
        all_apers.append(aper)
        all_apers_areas.append(aper.area)
        mask = aper.to_mask(method='exact')
        all_masks.append(mask)
        mask_data = mask.multiply(data)
        mask_weight = mask.multiply(ones)
        all_data.append(mask_data)
        all_weights.append(mask_weight)
        all_stds.append(twoD_weighted_std(mask_data, mask_weight))
    phot_table = aperture_photometry(data, all_apers)

    center_val = np.sum(all_data[0]) / all_apers_areas[0] + 5 * all_stds[0]

    delta_mags = []
    for i in range(len(phot_table[0]) - 3):
        try:
            delta_mags.append(-2.5 * math.log((np.sum(all_data[i])/all_apers_areas[i] + \
                                               5*all_stds[i])/center_val,10))
        except ValueError:
            print('annulus',i, 'relative flux equal to', (np.sum(all_data[i])/all_apers_areas[i] + \
                                               5*all_stds[i])/center_val, '...it is not included')
            delta_mags.append(np.NaN)

    arc_lengths = []
    for i in range(len(delta_mags)):
        arc_lengths.append(
            (i * 0.033 + 0.033) *
            radius_size)  #make sure center radius size is correct
    arc_lengths = np.array(arc_lengths)
    lim_arc_lengths = arc_lengths[arc_lengths < 10]
    delta_mags = delta_mags[:len(lim_arc_lengths)]
    delta_mags = np.array(delta_mags)
    if delta_mags[1] < 0:
        print('Warning: first annulus has negative relative flux of value,',
              '%.5f' % delta_mags[1],
              'consider changing center or radius size')

    return (lim_arc_lengths, delta_mags, all_stds)
示例#24
0
class RadialProfile:
    """Main function to calulate radial profiles

    Computes a radial profile of a source in an array.  This function
    leverages some of the tools in photutils to cutout the small region
    around the source.  This function can first recenter the source
    via a 2d Gaussian fit (radial profiles are sensitive to centroids)
    and then fit a 1D Moffat profile to the values.  The profile
    is calculated by computing the distance from the center of each
    pixel within a box of size r to the centroid of the source in the
    box.  Additionally, the profile and the fit can be plotted.
    If fit is set to True, then the profile is fit with a 1D Moffat.
    If show is set to True, then profile (and/or fit) is plotted.
    If an axes object is provided, the plot(s) will be on that object.
    NOTE: THE POSITIONS ARE 0 INDEXED (bottom left corner pixel
    center is set to (0,0)).


    Parameters
    ----------
    x : float
        The x position of the centroid of the source. ZERO INDEXED.
        stored in the .x attribute
    y : float
        The y position of the centroid of the source. ZERO INDEXED.
        .x attribute
    data : array
        A 2D array containing the full image data.  A small box
        is cut out of this array for the radial profile
    r : float, optional
        The size of the box used to cut out the source pixels.
        The box is typically square with side length ~ 2*r + 1.
        Default is 5 pix.
    fit:  bool
        Fit a 1D Moffat profile?  Default True.  Required for
        computation of FWHM.
    recenter : bool, optional
        Compute new centroid via 2D Gaussian fit?  Default False.
    show : bool, optional
        Plot the profile?  Default False.  See ax parameter for info.
    ax : matplotlib.axes.Axes, optional
        Axes object to make the plots on.  Default None.
        If None and show is True, an axes object will be created.

    Attributes
    ----------
    x : float
        The x position in pixels of the source centroid. Gets updated
        if the profile is recentered.
    y : float
        The y position in pixels of the source centroid. Gets updated
        if the profile is recentered.
    fwhm : float
        The FWHM of the fitted profile, only computed if fit=True
    old_x : float
        The x position in pixels of the original input centroid. Only
        set if recenter = True
    old_y : float
        The y position in pixels of the original input centroid. Only
        set if recenter = True
    fitted : bool
        Whether the data has had a profile fit. Only True if fit=True
        and fitting was successful
    is_empty : bool
        Whether cutout is empty or not.  True if position falls
        entirely off of data.
    cutout : array
        2D array containing small cutout of data around source
    distances : array
        Array containing distance to each pixel in cutout from centroid
    value : array
        Array containing all the values in the cutout
    """
    def __init__(self,
                 x,
                 y,
                 data,
                 r=5,
                 fit=True,
                 recenter=False,
                 show=False,
                 ax=None):
        self.x = x  # X position
        self.y = y  # Y Position
        self.r = r  # radius (acutally makes a box)
        self.is_empty = False  # if gets set True, cutout is empty
        self._setup_cutout(data)  # Make the cutout

        if recenter:
            self.recenter_source(data)  # recalculates centroid

        self.fit = fit
        self.fitted = False  # Initial state, set to true if fit success
        if self.is_empty:
            self.fwhm = np.nan

        else:
            self._create_profile()  # creates distances and values arrays

            if fit:
                self.fit_profile()  # performs fit, updates self.fitted
            if show:
                self.show_profile(ax)

    def _create_profile(self):
        """Compute distances to pixels in cutout"""
        iY, iX = np.mgrid[self.sy, self.sx]  # Pixel grid indices
        # extent = [sx.start, sx.stop-1, sy.start, sy.stop-1]

        self.distances = np.sqrt((iX - self.x)**2. +
                                 (iY - self.y)**2.).flatten()
        self.values = self.cutout.flatten()

    def _setup_cutout(self, data):
        """Cuts out the aperture and defines slice objects.
        General setup procedure.
        """
        self.ap = CircularAperture((self.x, self.y), r=self.r)
        mask = self.ap.to_mask()[0]
        self.sy = mask.bbox.slices[0]
        self.sx = mask.bbox.slices[1]
        self.cutout = mask.cutout(data, fill_value=np.nan)

        if self.cutout is None:
            self.is_empty = True

    def fit_profile(self):
        """Fits 1d Moffat function to measured radial profile.

        Fits a moffat profile to the distance and values of the pixels.
        Further development may allow user defined models.

        """
        try:
            amp0 = np.amax(self.values)
            bias0 = np.nanmedian(self.values)
            best_vals, covar = curve_fit(RadialProfile.profile_model,
                                         self.distances,
                                         self.values,
                                         p0=[amp0, 1.5, 1.5, bias0],
                                         bounds=([0., .3, .5, 0],
                                                 [np.inf, 10., 10., np.inf]))
            hwhm = best_vals[1] * np.sqrt(2.**(1. / best_vals[2]) - 1.)
            self.fwhm = 2 * hwhm
            self.amp, self.gamma, self.alpha, self.bias = best_vals
            self.fitted = True
            mod = RadialProfile.profile_model(self.distances, *best_vals)
            self.chisquared = chisquare(self.values, mod, ddof=4)[0]
        except Exception as e:
            print(e)
            self.amp, self.gamma, self.alpha, self.bias = [np.nan] * 4
            self.fwhm = np.nan
            self.fitted = False
            self.chisquared = np.nan

    @staticmethod
    def profile_model(r, amp, gamma, alpha, bias):
        """Returns 1D Moffat profile evaluated at r values.

        This function takes radius values and parameters in a simple 1D
        moffat profiles and returns the values of the profile at those
        radius values.  The model is defined as:
        model = amp * (1. + (r / gamma) ** 2.) ** (-1. * alpha) + bias

        Parameters
        ----------
        r : array
            The distances at which to sample the model
        amp : float
            The amplitude of the of the model
        gamma: float
            The width of the profile.
        alpha: float
            The decay of the profile.
        bias: float
            The bias level (piston term) of the data.  This is like a background
            value.

        Returns
        -------
        model : array
            The values of the model sampled at the r values.
        """
        model = amp * (1. + (r / gamma)**2.)**(-1. * alpha) + bias
        return model

    def recenter_source(self, data):
        """Recenters source position in cutout and updates x,y attributes"""

        # Archive old positions.
        self.old_x = self.x
        self.old_y = self.y

        if self.is_empty:
            self.x, self.y = np.nan, np.nan

        else:
            # Fit 2D gaussian
            xg1, yg1 = centroid_2dg(self.cutout)
            dx = xg1 + self.sx.start - self.x
            dy = yg1 + self.sy.start - self.y
            dr = (dx**2. + dy**2.)**.5
            if dr > 2.:
                print('Large shift of {},{} computed.'.format(dx, dy))
                print('Rejecting and keeping original x, y coordinates')

            else:
                self.x = xg1 + self.sx.start
                self.y = yg1 + self.sy.start
                self._setup_cutout(data)

    def show_profile(self, ax=None, show_fit=True):
        """Makes plot of radial profile

        Plots the radial profile, that is pixel distance vs
        pixel value.  Can plot on an existing axes object if
        the an axes object is passed in via the ax parameter.
        The function attempts to set sensible axes limits, specifically
        half of the smallest positive value (axes are logarithmic).
        The axes object is returned by this, so that parameters can
        be set by the user later.

        Parameters
        ----------
        ax : matplotlib.axes.Axes, optional
            An axes object to plot the radial profile on (for integrating)
            the plot into other figures.  If not set, the script will create
            an axes object.
        show_fit : bool, optional
            Plot the fitted model.  Only done if fit was successful.
        Returns
        -------
        ax : matplotlib.axes.Axes
            The axes object containing the radial profile plot/
        """
        if ax is None:
            fig = plt.figure()
            ax = fig.add_subplot(111)

        ax.scatter(self.distances, self.values, alpha=.5)
        min_y = np.amin(self.values[self.values > 0.]) / 2.
        ax.set_ylim(min_y, np.nanmax(self.values) * 2.)
        ax.set_xlim(0.)

        ax.set_yscale('log')
        ax.set_ylabel('Pixel Value')
        ax.set_xlabel('Distance from centroid [pix]')

        if self.fitted and show_fit:
            tmp_r = np.arange(0, np.ceil(np.amax(self.distances)), .1)
            model_fit = RadialProfile.profile_model(tmp_r, self.amp,
                                                    self.gamma, self.alpha,
                                                    self.bias)
            label = r'$\gamma$= {}, $\alpha$ = {}'.format(
                round(self.gamma, 2), round(self.alpha, 2))
            label += '\nFWHM = {}'.format(round(self.fwhm, 2))
            ax.plot(tmp_r, model_fit, label=label)
            ax.legend(loc=1)
        return ax
示例#25
0
            ann_patches = annulus.plot(color='red', lw=2, label='Background annulus')
            handles = (ap_patches[0],ann_patches[0])
            plt.legend(loc=(0.17, 0.05), facecolor='#458989', labelcolor='white', handles=handles, prop={'weight':'bold', 'size':11})
            plt.xlim(100,170)
            plt.ylim(200,256)
            #plt.savefig('./circle_ADI/ADI_32px_'+str(i))
            plt.show()

    return res, SN 

if __name__ == "__main__":

    print("###### Start to process the data ######")
    start_time = datetime.datetime.now() 
    positions = [(126.05284, 249.11)]
    aperture = CircularAperture(positions, r=2)
    annulus = CircularAnnulus(positions, r_in=4, r_out=6)

    # ADI data
    #ADI_res, ADI_SN = get_photometry("./ADI")
    #ADI_res, ADI_SN = get_photometry("./ADI_WITH_MASK")
    #ADI_res_32, ADI_SN_32 = get_photometry("./ADI_WITH_MASK_32")
    #print(ADI_res_32)

    # RDI data 1 target 2 ref stars
    #RDI_res_2_ref, RDI_2_SN = get_photometry("./RDI_ref_2_star")
    #print(RDI_res_2_ref)

    # RDI data 1 target 4 ref stars
    #RDI_res_4_ref, RDI_4_SN = get_photometry("./RDI_ref_4_star")
    #print(RDI_res_4_ref)
示例#26
0
def getCircularApetures(center,radius):
	positions = setCenters(center,radius)
	apetures = [CircularAperture(pos,r=radius) for pos in positions]
	return apetures
psfn = vip.metrics.normalize_psf(psf[wl_final], fwhm, size=17)
print("psfn =", psfn.shape, "psfn.ndim =", psfn.ndim)

if nb_wl > 1:
    fwhm_bis = get_fwhm_from_psf(psf[1])
    psfn_bis = vip.metrics.normalize_psf(psf[1], fwhm_bis, size=17)
    print("psfn =", psfn_bis.shape, "psfn.ndim =", psfn_bis.ndim)

# pxscale of IRDIS
pxscale = get_pxscale()

# get flux level
psf_nx, psf_ny = psf[wl_final].shape
position = (psf_nx // 2, psf_ny // 2)

aperture = CircularAperture(position, r=(diameter / 2))
annulus = CircularAnnulus(position, r_in=diameter, r_out=diameter * (3 / 2))
flux_psf = aperture_photometry(psf[wl_final], [aperture, annulus])
flux_psf['aperture_sum_0', 'aperture_sum_1'].info.format = '%.8g'
flux_level = flux_psf['aperture_sum_0'][0] * contrast

print(">> flux of psf in the same aperture is:", flux_psf['aperture_sum_0'][0],
      "contrast is:", contrast)
print(">> flux_level =", flux_level)

################################
# Step-3 do the fake injection #
################################

# use vip to inject a fake companion
science_cube_fake_comp = np.zeros((2, nb_science_frames, nx, ny))
示例#28
0
def extract_ifu(input_model, source_type, extract_params):
    """This function does the extraction.

    Parameters
    ----------
    input_model : IFUCubeModel
        The input model.

    source_type : string
        "POINT" or "EXTENDED"

    extract_params : dict
        The extraction parameters for aperture photometry.

    Returns
    -------
    ra, dec : float
        ra and dec are the right ascension and declination respectively
        at the nominal center of the image.

    wavelength : ndarray, 1-D
        The wavelength in micrometers at each plane of the IFU cube.

    temp_flux : ndarray, 1-D
        The sum of the data values in the extraction aperture minus the
        sum of the data values in the background region (scaled by the
        ratio of areas), for each plane.
        The data values are in units of surface brightness, so this value
        isn't really the flux, it's an intermediate value.  Dividing by
        `npixels` (to compute the average) will give the value for the
        `surf_bright` (surface brightness) column, and multiplying by
        the solid angle of a pixel will give the flux for a point source.

    background : ndarray, 1-D
        For point source data, the background array is the count rate that was subtracted
        from the total source data values to get `temp_flux`. This background is determined
        for annulus region. For extended source data, the background array is the sigma clipped
        extracted region.

    npixels : ndarray, 1-D, float64
        For each slice, this is the number of pixels that were added
        together to get `temp_flux`.

    dq : ndarray, 1-D, uint32
        The data quality array.

    npixels_bkg : ndarray, 1-D, float64
        For each slice, for point source data  this is the number of pixels that were added
        together to get `temp_flux` for an annulus region or for extended source
        data it is the number of pixels used to determine the background

    radius_match : ndarray,1-D, float64
        The size of the extract radius in pixels used at each wavelength of the IFU cube

    x_center, y_center : float
        The x and y center of the extraction region
    """

    data = input_model.data
    weightmap = input_model.weightmap

    shape = data.shape
    if len(shape) != 3:
        log.error("Expected a 3-D IFU cube; dimension is %d.", len(shape))
        raise RuntimeError("The IFU cube should be 3-D.")

    # We need to allocate temp_flux, background, npixels, and dq arrays
    # no matter what.  We may need to divide by npixels, so the default
    # is 1 rather than 0.
    temp_flux = np.zeros(shape[0], dtype=np.float64)
    background = np.zeros(shape[0], dtype=np.float64)
    npixels = np.ones(shape[0], dtype=np.float64)
    npixels_bkg = np.ones(shape[0], dtype=np.float64)

    dq = np.zeros(shape[0], dtype=np.uint32)

    # For an extended target, the entire aperture will be extracted, so
    # it makes no sense to shift the extraction location.
    if source_type != "EXTENDED":
        ra_targ = input_model.meta.target.ra
        dec_targ = input_model.meta.target.dec
        locn = locn_from_wcs(input_model, ra_targ, dec_targ)

        if locn is None or np.isnan(locn[0]):
            log.warning("Couldn't determine pixel location from WCS, so "
                        "source offset correction will not be applied.")

            x_center = float(shape[-1]) / 2.
            y_center = float(shape[-2]) / 2.

        else:
            (x_center, y_center) = locn
            log.info(
                "Using x_center = %g, y_center = %g, based on "
                "TARG_RA and TARG_DEC.", x_center, y_center)

    method = extract_params['method']
    subpixels = extract_params['subpixels']
    subtract_background = extract_params['subtract_background']

    radius = None
    inner_bkg = None
    outer_bkg = None
    width = None
    height = None
    theta = None
    # pull wavelength plane out of input data.
    # using extract 1d wavelength, interpolate the radius, inner_bkg, outer_bkg to match input wavelength

    # find the wavelength array of the IFU cube
    x0 = float(shape[2]) / 2.
    y0 = float(shape[1]) / 2.
    (ra, dec, wavelength) = get_coordinates(input_model, x0, y0)

    # interpolate the extraction parameters to the wavelength of the IFU cube
    radius_match = None
    if source_type == 'POINT':
        wave_extract = extract_params['wavelength'].flatten()
        inner_bkg = extract_params['inner_bkg'].flatten()
        outer_bkg = extract_params['outer_bkg'].flatten()
        radius = extract_params['radius'].flatten()

        frad = interp1d(wave_extract,
                        radius,
                        bounds_error=False,
                        fill_value="extrapolate")
        radius_match = frad(wavelength)
        # radius_match is in arc seconds - need to convert to pixels
        # the spatial scale is the same for all wavelengths do we only need to call compute_scale once.

        if locn is None:
            locn_use = (input_model.meta.wcsinfo.crval1,
                        input_model.meta.wcsinfo.crval2, wavelength[0])
        else:
            locn_use = (ra_targ, dec_targ, wavelength[0])

        scale_degrees = compute_scale(
            input_model.meta.wcs,
            locn_use,
            disp_axis=input_model.meta.wcsinfo.dispersion_direction)

        scale_arcsec = scale_degrees * 3600.00
        radius_match /= scale_arcsec

        finner = interp1d(wave_extract,
                          inner_bkg,
                          bounds_error=False,
                          fill_value="extrapolate")
        inner_bkg_match = finner(wavelength) / scale_arcsec

        fouter = interp1d(wave_extract,
                          outer_bkg,
                          bounds_error=False,
                          fill_value="extrapolate")
        outer_bkg_match = fouter(wavelength) / scale_arcsec

    elif source_type == 'EXTENDED':
        # Ignore any input parameters, and extract the whole image.
        width = float(shape[-1])
        height = float(shape[-2])
        x_center = width / 2. - 0.5
        y_center = height / 2. - 0.5
        theta = 0.
        subtract_background = False
        bkg_sigma_clip = extract_params['bkg_sigma_clip']

    log.debug("IFU 1-D extraction parameters:")
    log.debug("  x_center = %s", str(x_center))
    log.debug("  y_center = %s", str(y_center))
    if source_type == 'POINT':
        log.debug("  method = %s", method)
        if method == "subpixel":
            log.debug("  subpixels = %s", str(subpixels))
    else:
        log.debug("  width = %s", str(width))
        log.debug("  height = %s", str(height))
        log.debug("  theta = %s degrees", str(theta))
        log.debug("  subtract_background = %s", str(subtract_background))
        log.debug("  sigma clip value for background = %s",
                  str(bkg_sigma_clip))
        log.debug("  method = %s", method)
        if method == "subpixel":
            log.debug("  subpixels = %s", str(subpixels))

    position = (x_center, y_center)

    # get aperture for extended it will not change with wavelength
    if source_type == 'EXTENDED':
        aperture = RectangularAperture(position, width, height, theta)
        annulus = None

    for k in range(shape[0]):  # looping over wavelength
        inner_bkg = None
        outer_bkg = None

        if source_type == 'POINT':
            radius = radius_match[
                k]  # this radius has been converted to pixels
            aperture = CircularAperture(position, r=radius)
            inner_bkg = inner_bkg_match[k]
            outer_bkg = outer_bkg_match[k]
            if inner_bkg <= 0. or outer_bkg <= 0. or inner_bkg >= outer_bkg:
                log.debug("Turning background subtraction off, due to "
                          "the values of inner_bkg and outer_bkg.")
                subtract_background = False

        if subtract_background and inner_bkg is not None and outer_bkg is not None:
            annulus = CircularAnnulus(position,
                                      r_in=inner_bkg,
                                      r_out=outer_bkg)
        else:
            annulus = None

        subtract_background_plane = subtract_background
        # Compute the area of the aperture and possibly also of the annulus.
        # for each wavelength bin (taking into account empty spaxels)
        normalization = 1.
        temp_weightmap = weightmap[k, :, :]
        temp_weightmap[temp_weightmap > 1] = 1
        aperture_area = 0
        annulus_area = 0

        # aperture_photometry - using weight map
        phot_table = aperture_photometry(temp_weightmap,
                                         aperture,
                                         method=method,
                                         subpixels=subpixels)

        aperture_area = float(phot_table['aperture_sum'][0])
        log.debug("aperture.area = %g; aperture_area = %g", aperture.area,
                  aperture_area)

        if (aperture_area == 0 and aperture.area > 0):
            aperture_area = aperture.area

        if subtract_background and annulus is not None:
            # Compute the area of the annulus.
            phot_table = aperture_photometry(temp_weightmap,
                                             annulus,
                                             method=method,
                                             subpixels=subpixels)
            annulus_area = float(phot_table['aperture_sum'][0])
            log.debug("annulus.area = %g; annulus_area = %g", annulus.area,
                      annulus_area)

            if (annulus_area == 0 and annulus.area > 0):
                annulus_area = annulus.area

            if annulus_area > 0.:
                normalization = aperture_area / annulus_area
            else:
                log.warning("Background annulus has no area, so background "
                            f"subtraction will be turned off. {k}")
                subtract_background_plane = False

        npixels[k] = aperture_area
        npixels_bkg[k] = 0.0
        if annulus is not None:
            npixels_bkg[k] = annulus_area
        # aperture_photometry - using data

        phot_table = aperture_photometry(data[k, :, :],
                                         aperture,
                                         method=method,
                                         subpixels=subpixels)
        temp_flux[k] = float(phot_table['aperture_sum'][0])

        # Point source type of data with defined annulus size
        if subtract_background_plane:
            bkg_table = aperture_photometry(data[k, :, :],
                                            annulus,
                                            method=method,
                                            subpixels=subpixels)
            background[k] = float(bkg_table['aperture_sum'][0])
            temp_flux[k] = temp_flux[k] - background[k] * normalization

        # Extended source data - background determined from sigma clipping
        if source_type == 'EXTENDED':
            bkg_data = data[k, :, :]
            # pull out the data with coverage in IFU cube. We do not want to use
            # the edge data that is zero to define the statistics on clipping
            bkg_stat_data = bkg_data[temp_weightmap == 1]

            bkg_mean, _, bkg_stddev = stats.sigma_clipped_stats(
                bkg_stat_data, sigma=bkg_sigma_clip, maxiters=5)
            low = bkg_mean - bkg_sigma_clip * bkg_stddev
            high = bkg_mean + bkg_sigma_clip * bkg_stddev

            # set up the mask to flag data that should not be used in aperture photometry
            maskclip = np.logical_or(bkg_data < low, bkg_data > high)

            bkg_table = aperture_photometry(bkg_data,
                                            aperture,
                                            mask=maskclip,
                                            method=method,
                                            subpixels=subpixels)
            background[k] = float(bkg_table['aperture_sum'][0])
            phot_table = aperture_photometry(temp_weightmap,
                                             aperture,
                                             mask=maskclip,
                                             method=method,
                                             subpixels=subpixels)
            npixels_bkg[k] = float(phot_table['aperture_sum'][0])

        del temp_weightmap
        # done looping over wavelength bins
    # Check for NaNs in the wavelength array, flag them in the dq array,
    # and truncate the arrays if NaNs are found at endpoints (unless the
    # entire array is NaN).
    (wavelength, temp_flux, background, npixels, dq, npixels_bkg) = \
        nans_in_wavelength(wavelength, temp_flux, background, npixels, dq, npixels_bkg)

    return (ra, dec, wavelength, temp_flux, background, npixels, dq,
            npixels_bkg, radius_match, x_center, y_center)