示例#1
0
def compute_photutils(settings, image_data):
    # Taken from photuils example http://photutils.readthedocs.io/en/stable/psf.html
    # See also http://photutils.readthedocs.io/en/stable/api/photutils.psf.DAOPhotPSFPhotometry.html#photutils.psf.DAOPhotPSFPhotometry

    sigma_psf = settings.sigma_psf
    crit_separation = settings.crit_separation
    threshold = settings.threshold
    box_size = settings.box_size
    niters = settings.iters

    bkgrms = MADStdBackgroundRMS(SigmaClip(sigma=3.))
    std = bkgrms(image_data)

    logger.info('Using sigma=%f, threshold=%f, separation=%f, box_size=%d, niters=%d, std=%f' % \
                (sigma_psf, threshold, crit_separation, box_size, niters, std))
    fitter = LevMarLSQFitter()
    # See findpars args http://stsdas.stsci.edu/cgi-bin/gethelp.cgi?findpars
    photargs = {
        'crit_separation':
        crit_separation * sigma_psf * gaussian_sigma_to_fwhm,
        #'crit_separation': crit_separation,
        'threshold': threshold * std,
        'fwhm': sigma_psf * gaussian_sigma_to_fwhm,
        'sigma_radius': sigma_psf * gaussian_sigma_to_fwhm,
        #'sigma': 3.0,
        'fitter': fitter,
        'niters': niters,
        'fitshape': (box_size, box_size),
        'sharplo': 0.2,
        'sharphi': 2.0,
        'roundlo': -1.0,
        'roundhi': 1.0,
        'psf_model': IntegratedGaussianPRF(sigma=sigma_psf),
        'aperture_radius': sigma_psf * gaussian_sigma_to_fwhm,
    }

    # starfinder takes 'exclude border'

    # photargs['psf_model'].sigma.fixed = False

    photometry = DAOPhotPSFPhotometry(**photargs)

    # Column names:
    # 'flux_0', 'x_fit', 'x_0', 'y_fit', 'y_0', 'flux_fit', 'id', 'group_id',
    # 'flux_unc', 'x_0_unc', 'y_0_unc', 'iter_detected'
    result_tab = photometry(image=image_data)

    # Only use from final iteration
    # result_tab = result_tab[result_tab['iter_detected'] == niters]

    logger.info('Fit info: %s' % fitter.fit_info['message'])

    # Filter out negative flux
    #result_tab = result_tab[result_tab['flux_fit'] >= 0]

    # Formula: https://en.wikipedia.org/wiki/Instrumental_magnitude
    result_tab['mag'] = -2.5 * np.log10(result_tab['flux_fit'])
    result_tab['mag_unc'] = np.abs(-2.5 * np.log10(result_tab['flux_fit'] + result_tab['flux_unc']) - \
                                   -2.5 * np.log10(result_tab['flux_fit'] - result_tab['flux_unc'])) / 2.0

    # http://www.ucolick.org/~bolte/AY257/s_n.pdf
    #result_tab['snr'] = 1.0875 / result_tab['mag_unc']
    result_tab['snr'] = 1.0 / (np.power(10, (result_tab['mag_unc'] / 2.5)) - 1)

    residual_image = photometry.get_residual_image()

    return result_tab, residual_image, std
示例#2
0
psf.y_0.fixed = True
pos = Table(names=['x_0', 'y_0'],
            data=[catalog['X_IMAGE_DBL'],
                  catalog['Y_IMAGE_DBL']])  # Using the initial positions

from photutils.psf import DAOPhotPSFPhotometry

photometry = DAOPhotPSFPhotometry(
    crit_separation=
    19,  # The higher the crit_separation, the higher the computational cost
    threshold=1.0,
    fwhm=3.0,
    psf_model=psf,
    fitshape=9,
    sigma=3.0,
    ratio=1.0,
    theta=0.0,
    sigma_radius=1.5,
    sharplo=0.2,
    sharphi=1.0,
    roundlo=-1.0,
    roundhi=1.0,
    fitter=LevMarLSQFitter(),
    niters=3,
    aperture_radius=5)

import timeit

tic = timeit.default_timer()

phot_results = photometry(image_data, init_guesses=pos)
residual = photometry.get_residual_image()
示例#3
0
def daophot(cnam, ccd, xlo, xhi, ylo, yhi, niters, method, fwhm, beta, gfac,
            thresh, rejthresh):
    """
    Perform iterative PSF photometry and star finding on region of CCD
    """
    print(xlo, ylo, xhi, yhi)
    # first check we are within a single window
    wnam1 = ccd.inside(xlo, ylo, 2)
    wnam2 = ccd.inside(xhi, yhi, 2)
    if wnam1 != wnam2:
        raise hcam.HipercamError(
            'PSF photometry cannot currently be run across seperate windows')
    wnam = wnam1
    print(wnam)
    # background stats from whole windpw
    # estimate background RMS
    wind = ccd[wnam]

    rms_func = MADStdBackgroundRMS(sigma_clip=SigmaClip(sigma=rejthresh))
    bkg_rms = rms_func(wind.data)
    bkg_func = MMMBackground(sigma_clip=SigmaClip(sigma=rejthresh))
    bkg = bkg_func(wind.data)
    print('  Background estimate = {}, BKG RMS = {}'.format(bkg, bkg_rms))

    # crop window to ROI
    wind = ccd[wnam].window(xlo, xhi, ylo, yhi)

    # correct FWHM for binning
    fwhm /= wind.xbin
    if method == 'm':
        psf_model = MoffatPSF(fwhm, beta)
        print('  FWHM = {:.1f}, BETA={:.1f}'.format(fwhm, beta))
    else:
        psf_model = IntegratedGaussianPRF(sigma=fwhm * gaussian_fwhm_to_sigma)
        print('  FWHM = {:.1f}'.format(fwhm))

    # region to extract around positions for fits
    fitshape = int(5 * fwhm)
    # ensure odd
    if fitshape % 2 == 0:
        fitshape += 1

    photometry_task = DAOPhotPSFPhotometry(gfac * fwhm,
                                           thresh * bkg_rms,
                                           fwhm,
                                           psf_model,
                                           fitshape,
                                           niters=niters,
                                           sigma=rejthresh)

    with warnings.catch_warnings():
        warnings.simplefilter('ignore')
        results = photometry_task(wind.data - bkg)

    # filter out junk fits
    tiny = 1e-30
    bad_errs = (results['flux_unc'] < tiny) | (results['x_0_unc'] < tiny) | (
        results['y_0_unc'] < tiny)
    results = results[~bad_errs]

    results.write('table_{}.fits'.format(cnam))
    print('  found {} stars'.format(len(results)))

    xlocs, ylocs = results['x_fit'], results['y_fit']

    # convert to device coordinates
    xlocs = wind.x(xlocs)
    ylocs = wind.y(ylocs)
    return xlocs, ylocs
示例#4
0
def run_daophot(image,
                threshold,
                star_tbl,
                niters=1,
                snr_lim=5,
                duet=None,
                diag=False):
    '''
        Given an image and a PSF, go run DAOPhot PSF-fitting algorithm
    '''
    from photutils.psf import DAOPhotPSFPhotometry, IntegratedGaussianPRF

    if duet is None:
        duet = Telescope()

    fwhm = (duet.psf_fwhm / duet.pixel).to('').value

    # Fix star table columns
    star_tbl['x_0'] = star_tbl['x']
    star_tbl['y_0'] = star_tbl['y']

    # Define a fittable PSF model
    sigma = fwhm / (2. * np.sqrt(2 * np.log(2)))
    # Simple Gaussian model to fit
    #psf_model = IntegratedGaussianPRF(sigma=sigma)
    #flux_norm = 1

    # Use DUET-like PSF
    #oversample = 2 # Needs to be oversampled but only minimally
    #duet_psf_os = duet.psf_model(pixel_size=duet.pixel/oversample, x_size=12, y_size=12) # Even numbers work better
    #psf_model = EPSFModel(duet_psf_os.array,oversampling=oversample)
    #flux_norm = 1/oversample**2 # A quirk of constructing an oversampled ePSF using photutils
    psf_model = duet.epsf_model

    # Temporarily turn off Astropy warnings
    import warnings
    from astropy.utils.exceptions import AstropyWarning
    warnings.simplefilter('ignore', category=AstropyWarning)

    ## FROM HERE ON NO UNITS ###########
    # Initialise a Photometry object
    # This object loops find, fit and subtract
    threshold = threshold.to(image.unit)
    photometry = DAOPhotPSFPhotometry(fwhm,
                                      threshold.value,
                                      fwhm,
                                      psf_model, (5, 5),
                                      niters=niters,
                                      sigma_radius=5,
                                      aperture_radius=fwhm)

    # Problem with _recursive_lookup while fitting (needs latest version of astropy fix to modeling/utils.py)
    result = photometry(image=image.value, init_guesses=star_tbl)
    residual_image = photometry.get_residual_image()

    # Filter results to only keep those with S/N greater than snr_lim (default is 5)
    result_sig = result[np.abs(result['flux_fit'] /
                               result['flux_unc']) >= snr_lim]

    if diag:
        print("PSF-fitting complete")

    # Turn warnings back on again
    warnings.simplefilter('default')
    ## FROM HERE ON YES UNITS ###########
    result_sig['flux_fit'] = result_sig['flux_fit'] * image.unit
    result_sig['flux_unc'] = result_sig['flux_unc'] * image.unit

    return result_sig, residual_image * image.unit
示例#5
0
    def get_photometry(self,
                       aperture_radius=3,
                       fwhm=None,
                       sky_radius_inner=None,
                       sky_radius_outer=None,
                       mag_zero_point=0,
                       mode="basic"):

        if sky_radius_outer is None:
            sky_radius_outer = np.min(self.image.shape) // 2
        if sky_radius_inner is None:
            sky_radius_inner = sky_radius_outer - 3

        x, y = np.array(self.image.shape) // 2

        r = aperture_radius
        ro = sky_radius_outer
        dw = sky_radius_outer - sky_radius_inner

        bg = np.copy(self.image[y - ro:y + ro, x - ro:x + ro])
        bg[dw:-dw, dw:-dw] = 0
        bg_median = np.median(bg[bg != 0])
        bg_std = np.std(bg[bg != 0])
        noise = bg_std * np.sqrt(np.sum(bg != 0))

        im = np.copy(self.image[y - r:y + r, x - r:x + r])

        if "circ" in mode.lower():
            pass

        elif "basic" in mode.lower():
            flux = np.sum(im - bg_median)
            self.results = None

        elif "psf" in mode.lower():

            if fwhm is None:
                warnings.warn("``fwhm`` must be given for PSF photometry")
                flux = 0

            try:
                x, y = self._find_center(self.image, fwhm)
                flux = self._basic_psf_flux(self.image, fwhm, x=x, y=y)
                ##### Really bad form!!! Keep this in mind =)
                self.x, self.y = x, y
            except:
                flux = 0

        elif "dao" in mode.lower():

            if fwhm is None:
                warnings.warn("``fwhm`` must be given for PSF photometry")
                flux = 0

            sigma = fwhm / 2.35
            prf = IntegratedGaussianPRF(sigma)
            fitshape = im.shape[0] if im.shape[0] % 2 == 1 else im.shape[0] - 1

            daophot = DAOPhotPSFPhotometry(crit_separation=sigma,
                                           threshold=np.median(im),
                                           fwhm=fwhm,
                                           psf_model=prf,
                                           fitshape=fitshape)

            #try:
            results = daophot(im)

            width, height = im.shape
            dist_from_centre = np.sqrt((results["x_fit"] - width  / 2)**2 + \
                                       (results["y_fit"] - height / 2)**2)

            i = np.argmin(dist_from_centre)
            x, y = results["x_fit"][i], results["y_fit"][i],
            flux = results["flux_fit"][i]

            ##### Really bad form!!! Keep this in mind =)
            self.x, self.y = x, y
            self.results = results

            #except:
            #    self.results = None
            #   flux = 0

        snr = flux / noise
        mag = -2.5 * np.log10(flux) + mag_zero_point

        return mag, snr, flux, noise, bg_std, bg_median
		daogroup = DAOGroup(2.0*fwhm)
		
		mmm_bkg = MMMBackground()
		fitter = LevMarLSQFitter()
		psf_model = IntegratedGaussianPRF(sigma=(fwhm/gaussian_sigma_to_fwhm))
		
		#fitshape must be odd
		fitshape = 2*int(fwhm)+1
	
		print 'Performing photometry'
		#photometry = IterativelySubtractedPSFPhotometry(finder=iraffind, group_maker=daogroup, bkg_estimator=mmm_bkg, psf_model=psf_model,fitter=LevMarLSQFitter(), niters=None, fitshape=(fitshape, fitshape), aperture_radius=fwhm)
		#niters = None means continue until all stars subtracted - might recur infinitely
		
		
		from photutils.psf import DAOPhotPSFPhotometry
		photometry =  DAOPhotPSFPhotometry(crit_separation=3*fwhm, threshold=3.5*std, fwhm=fwhm, psf_model=psf_model, fitshape=(fitshape, fitshape), sharplo=0.0, sharphi=2.0, roundlo=-5.0, roundhi=5.0, fitter=iraffind, niters=100, aperture_radius=1.2*fwhm)
		raw_input('Done')
		
		print 'Results table'
		result_tab = photometry(image=image)
		
		raw_input( 'Creating residual image')
		residual_image = photometry.get_residual_image()
		
		print 'Plotting'
		plt.subplot(1, 2, 1)
		plt.imshow(image, cmap='viridis', aspect=1, interpolation='nearest', origin='lower')
		plt.colorbar(orientation='horizontal', fraction=0.046, pad=0.04)
		plt.subplot(1 ,2, 2)
		plt.imshow(residual_image, cmap='viridis', aspect=1, interpolation='nearest', origin='lower')
		plt.title('Residual Image')