예제 #1
0
def bkg_subtraction(time, flux, scope="tpf", sigma=3):
    """Subtracts background flux from target pixel file.

    Parameters
    ----------
    scope : string, "tpf" or "postcard"
        If `tpf`, will use data from the target pixel file only to estimate and remove the background.
        If `postcard`, will use data from the entire postcard region to estimate and remove the background.
    sigma : float
        The standard deviation cut used to determine which pixels are representative of the background in each cadence.
    """

    tpf_flux_bkg = []

    sigma_clip = SigmaClip(sigma=sigma)
    #    bkg = MMMBackground(sigma_clip=sigma_clip)
    bkg = SExtractorBackground(sigma_clip=sigma_clip)

    bkg_MMM = MMMBackground(sigma_clip=sigma_clip)
    bkg_ModeEstimator = ModeEstimatorBackground(median_factor=3.,
                                                mean_factor=2.,
                                                sigma_clip=sigma_clip)
    bkg_Mean = MeanBackground(sigma_clip)
    bkg_Median = MedianBackground(sigma_clip)
    bkg_SExtractor = SExtractorBackground(sigma_clip)

    bkg_MMM_value = bkg_MMM.calc_background(flux[0])
    bkg_ModeEstimator_value = bkg_ModeEstimator.calc_background(flux[0])
    bkg_Mean_value = bkg_Mean.calc_background(flux[0])
    bkg_Median_value = bkg_Median.calc_background(flux[0])
    bkg_SExtractor_value = bkg_SExtractor.calc_background(flux[0])

    print("MMM Background = {}".format(bkg_MMM_value))
    print("ModeEstimator Background = {}".format(bkg_ModeEstimator_value))
    print("Mean Background = {}".format(bkg_Mean_value))
    print("Median Background = {}".format(bkg_Median_value))
    print("SExtractor Background = {}".format(bkg_SExtractor_value))

    for i in range(len(time)):
        bkg_value = bkg.calc_background(flux[i])
        tpf_flux_bkg.append(bkg_value)

    tpf_flux_bkg = np.array(tpf_flux_bkg)

    return tpf_flux_bkg
예제 #2
0
def bkg_estimation(filename,
                   box=(20, 20),
                   filter_size=(3, 3),
                   bkg_estimator='SExtractor',
                   sigma=3.,
                   sigma_lower=None,
                   sigma_upper=None,
                   maxiters=10,
                   outLevel=1):

    imagelist = np.atleast_1d(filename)
    for ima in imagelist:
        print("\nEstimate background in %s" % ima)
        root = os.path.splitext(ima)[0]

        hdulist = fits.open(ima)
        data = hdulist[0].data

        sigma_clip = SigmaClip(sigma=sigma,
                               sigma_lower=sigma_lower,
                               sigma_upper=sigma_upper,
                               maxiters=maxiters)

        if bkg_estimator == 'SExtractor':
            bkg_estimator = SExtractorBackground()
        elif bkg_estimator == 'MMM':
            bkg_estimator = MMMBackground()
        elif bkg_estimator == 'ModeEstimator':
            bkg_estimator = ModeEstimatorBackground()
        elif bkg_estimator == 'Median':
            bkg_estimator = MedianBackground()
        elif bkg_estimator == 'Mean':
            bkg_estimator = MeanBackground()

        bkg = Background2D(
            data,
            box,
            filter_size=filter_size,
            sigma_clip=sigma_clip,
            bkg_estimator=bkg_estimator,
        )

        #  Create image with background substracted
        hdulist[0].data = data - bkg.background
        hdulist.writeto(ima, overwrite=True)

        if outLevel == 2:
            #  Create image with 2D background
            bkg_file = root + "_bkg_map.fits"
            hdulist[0].data = bkg.background
            hdulist.writeto(bkg_file, overwrite=True)
예제 #3
0
def bkg_sub(img,
            mask,
            sigma=5,
            bkg_estimator='median',
            box=(10, 2),
            filter_size=(1, 1)):
    """
    Completes a step for fitting a 2D background
    model.
    
    Parameters
    ----------
    img : np.ndarray
       Single exposure frame.
    mask : np.ndarray
       Mask to remove the orders.
    sigma : float, optional
       Sigma to remove above. Default is 5.
    bkg_estimator : str, optional
       Which type of 2D background model to use.
       Default is `median`.
    box : tuple, optional
       Box size by which to smooth over. Default
       is (10,2) --> prioritizes smoothing by
       column.
    filter_size : tuple, optional
       The window size of the 2D filter to apply to the
       low-resolution background map. Default is (1,1).

    Returns
    -------
    background : np.ndarray
       The modeled background image.
    """
    sigma_clip = SigmaClip(sigma=sigma)

    if bkg_estimator.lower() == 'mmmbackground':
        bkg = MMMBackground()
    elif bkg_estimator.lower() == 'median':
        bkg = MedianBackground()

    b = Background2D(img,
                     box,
                     filter_size=filter_size,
                     bkg_estimator=bkg,
                     sigma_clip=sigma_clip,
                     fill_value=0.0,
                     mask=mask)
    return b.background
예제 #4
0
    def bkg_subtraction(self, scope="tpf", sigma=1.2):
        """Subtracts background flux from target pixel file.

        Parameters
        ----------
        scope : string, "tpf" or "postcard"
            If `tpf`, will use data from the target pixel file only to estimate and remove the background.
            If `postcard`, will use data from the entire postcard region to estimate and remove the background.
        sigma : float
            The standard deviation cut used to determine which pixels are representative of the background in each cadence.
        """
        time = self.time
        flux = self.bkg_tpf

        self.tpf_flux_bkg = []

        sigma_clip = SigmaClip(sigma=sigma)
        bkg = MMMBackground(sigma_clip=sigma_clip)

        for i in range(len(time)):
            bkg_value = bkg.calc_background(flux[i])
            self.tpf_flux_bkg.append(bkg_value)

        self.tpf_flux_bkg = np.array(self.tpf_flux_bkg)
예제 #5
0
def subtract_sky_ccd_2d(ccd, skysub='SKYSUB', skyval='SKYVAL', box_size=(50,50), filter_size=(3,3), bkg_method='sextractor', 
	check_skysub=True, max_val=10000, fitsky=None, sigma=3., iters=10, edge_method='crop'):
    # Although edge_method='pad' is recommended, it does give errors "total size of new array must be unchanged" for v0.3
    if check_skysub and skysub is not None and skysub in ccd.header and ccd.header[skysub]:
        return ccd
    if not check_skysub and skysub is not None and skysub in ccd.header and ccd.header[skysub]:
        print ('WARNING: Image already sky subtracted! Subtracting AGAIN the sky! [set check_skysub = True for checking]')

    dsky = {'median': MedianBackground(), 'mean': MeanBackground(), 'sextractor': SExtractorBackground(), 
	'biweight': BiweightLocationBackground(), 'mode': ModeEstimatorBackground(), 'mm': MMMBackground()}

    if not bkg_method in dsky:
        print ('WARNING: Background type "%s" NOT available!! Selecting "median" from [%s]' % (bkg_type, ' | '.join(dksy.keys())))
        bkg_estimator = dksy['median']
    else:
        bkg_estimator = dsky[bkg_method]

    sigma_clip = SigmaClip(sigma=sigma, iters=iters) if sigma is not None and iters is not None else None

    bkg = Background2D(ccd.data, box_size, filter_size=filter_size, sigma_clip=sigma_clip, bkg_estimator=bkg_estimator, edge_method=edge_method)

    if max_val is not None and bkg.background_median >= max_val:
        if 'FILENAME' in ccd.header:
            print ('WARNING: File "%s" has high sky level (%s >= %s). Correction NOT applied' % (ccd.header['FILENAME'], bkg.background_median, max_val))
        else:
            print ('WARNING: File has high sky level (%s >= %s). Correction NOT applied' % (bkg.background_median, max_val))
        return ccd
    ccd.data -= bkg.background
    ccd.header[skysub] = True
    ccd.header[skyval] = bkg.background_median
    ccd.header['SKYTYPE'] = '2D'
    ccd.header['BKGTYPE'] = bkg_method
    ccd.bkg = bkg
    if fitsky is not None:
        pyfits.writeto(fitsky, bkg.background, clobber=True)
    return ccd
예제 #6
0
    def __init__(self,
                 config: config.Config,
                 image: Union[str, np.ndarray],
                 input_table: Optional[Table] = None):
        self.config = config

        self.tables = TableSet(input_table)

        self._image = None
        self.image_name = 'unnamed'
        if image is not None:
            self.image = image

        if config.use_catalogue_positions:
            if self.tables.input_table is None:
                raise ValueError(
                    'Need an input catalogue to if we want to use catalogue positions'
                )

        self.starfinder = DAOStarFinder(threshold=self.image_stats.threshold,
                                        fwhm=config.fwhm_guess,
                                        sigma_radius=config.sigma_radius,
                                        sharplo=config.sharplo,
                                        sharphi=config.sharphi,
                                        roundlo=config.roundlo,
                                        roundhi=config.roundhi,
                                        exclude_border=config.exclude_border)
        self.grouper = DAOGroup(config.separation_factor * config.fwhm_guess)
        self.fitter = LevMarLSQFitter()
        self.background = MMMBackground()
        self.photometry = None

        self.epsfstars: Optional[photutils.EPSFStars] = None
        self.epsf: Optional[photutils.EPSFModel] = None
        self.fwhm: Optional[float] = None
        self.residual = None
예제 #7
0
 def bkg(self):
     sigma_clip = SigmaClip(sigma=3.)
     bkg = MMMBackground(sigma_clip=sigma_clip)
     b = bkg.calc_background(self.flux, axis=(1, 2))
     return b
예제 #8
0
def psfphotometry(imagefile,
                  ra=None,
                  dec=None,
                  x=None,
                  y=None,
                  fwhm=5.0,
                  zp=0.0,
                  gain=1.0,
                  doDifferential=False,
                  xfield=None,
                  yfield=None,
                  xfirst=None,
                  yfirst=None):

    hdulist = fits.open(imagefile)
    header = fits.getheader(imagefile)

    if x == None:
        w = WCS(header)
        x0, y0 = w.wcs_world2pix(ra, dec, 1)
        gain = 1.0
    else:
        x0, y0 = x, y

    if len(hdulist) > 3:
        image = hdulist[1].data
    elif len(hdulist) == 2:
        image = hdulist[0].data
    else:
        image = hdulist[0].data
    image_shape = image.shape

    #daogroup = DAOGroup(crit_separation=8)
    daogroup = DAOGroup(crit_separation=25)

    mmm_bkg = MMMBackground()
    #iraffind = IRAFStarFinder(threshold=2.0*mmm_bkg(image),
    #                          fwhm=4.0)
    fitter = LevMarLSQFitter()
    gaussian_prf = IntegratedGaussianPRF(flux=1, sigma=1.7)
    gaussian_prf.sigma.fixed = False
    gaussian_prf.flux.fixed = False

    psffile = imagefile.replace(".fits", ".psf")
    fid = open(psffile, 'w')

    if len(image_shape) == 3:

        nhdu, xshape, yshape = image.shape
        dateobs = utcparser(hdulist[0].header["UTCSTART"])
        mjd = dateobs.mjd

        if "KINCYCTI" in hdulist[0].header:
            mjdall = mjd + np.arange(
                nhdu) * hdulist[0].header["KINCYCTI"] / 86400.0
        else:
            mjdall = mjd + np.arange(
                nhdu) * hdulist[0].header["EXPTIME"] / 86400.0

        mjds, mags, magerrs, fluxes, fluxerrs = [], [], [], [], []
        for jj in range(nhdu):
            if np.mod(jj, 10) == 0:
                print('PSF fitting: %d/%d' % (jj, nhdu))

            image = hdulist[0].data[jj, :, :]
            mjd = mjdall[jj]

            n, median, std = sigma_clipped_stats(image, sigma=3.0)
            daofind = DAOStarFinder(fwhm=2.0, threshold=2. * std)

            #phot_obj = IterativelySubtractedPSFPhotometry(finder=daofind,
            #                                              group_maker=daogroup,
            #                                              bkg_estimator=mmm_bkg,
            #                                              psf_model=gaussian_prf,
            #                                              fitter=fitter,
            #                                              fitshape=(21, 21),
            #                                              niters=10)

            image = image - np.median(image)
            image_slice = np.zeros(image.shape)

            slsize = 25
            xmin = np.max([0, int(x0 - slsize)])
            xmax = np.min([int(x0 + slsize), image.shape[0]])
            ymin = np.max([0, int(y0 - slsize)])
            ymax = np.min([int(y0 + slsize), image.shape[1]])
            image_slice[ymin:ymax, xmin:xmax] = 1

            if doDifferential:
                xmin_f = np.max([0, int(xfield - slsize)])
                xmax_f = np.min([int(xfield + slsize), image.shape[0]])
                ymin_f = np.max([0, int(yfield - slsize)])
                ymax_f = np.min([int(yfield + slsize), image.shape[1]])
                image_slice[ymin_f:ymax_f, xmin_f:xmax_f] = 1

            image = image * image_slice

            if (xfirst is None) or (yfirst is None):
                phot_obj = BasicPSFPhotometry(finder=daofind,
                                              group_maker=daogroup,
                                              psf_model=gaussian_prf,
                                              fitter=fitter,
                                              fitshape=(21, 21),
                                              bkg_estimator=mmm_bkg)
                phot_results = phot_obj(image)
            else:
                gaussian_prf = IntegratedGaussianPRF(flux=1, sigma=1.7)
                gaussian_prf.sigma.fixed = False
                gaussian_prf.flux.fixed = False
                gaussian_prf.x_0.fixed = False
                gaussian_prf.y_0.fixed = False

                phot_obj = BasicPSFPhotometry(group_maker=daogroup,
                                              psf_model=gaussian_prf,
                                              fitter=fitter,
                                              fitshape=(21, 21),
                                              bkg_estimator=mmm_bkg)

                pos = Table(names=['x_0', 'y_0'],
                            data=[[xfirst, xfield], [yfirst, yfield]])
                phot_results_tmp = phot_obj(image, init_guesses=pos)
                resimage = phot_obj.get_residual_image()

                pos = Table(names=['x_0', 'y_0'], data=[[x0], [y0]])

                gaussian_prf = IntegratedGaussianPRF(flux=1, sigma=1.7)
                gaussian_prf.sigma.fixed = False
                gaussian_prf.flux.fixed = False
                gaussian_prf.x_0.fixed = True
                gaussian_prf.y_0.fixed = True

                phot_obj = BasicPSFPhotometry(group_maker=daogroup,
                                              psf_model=gaussian_prf,
                                              fitter=fitter,
                                              fitshape=(7, 7),
                                              bkg_estimator=mmm_bkg)

                phot_results = phot_obj(resimage, init_guesses=pos)

                phot_results = vstack([phot_results_tmp, phot_results])

            #if True:
            if False:
                #sources = iraffind(image)
                sources = daofind(image)
                import matplotlib.pyplot as plt

                positions = np.transpose(
                    (sources['ycentroid'], sources['xcentroid']))
                apertures = CircularAperture(positions, r=4.)
                fig, axs = plt.subplots(1, 2)
                plt.axes(axs[0])
                plt.imshow(image.T,
                           origin='lower',
                           cmap='viridis',
                           aspect=1,
                           interpolation='nearest',
                           vmin=np.percentile(image[image > 0], 10),
                           vmax=np.percentile(image[image > 0], 90))
                apertures.plot(color='red')
                plt.xlim([ymin, ymax])
                plt.ylim([xmin, xmax])

                resimage = phot_obj.get_residual_image()
                plt.axes(axs[1])
                plt.imshow(resimage.T,
                           origin='lower',
                           cmap='viridis',
                           aspect=1,
                           interpolation='nearest',
                           vmin=0,
                           vmax=np.percentile(resimage[resimage > 0], 90))
                apertures.plot(color='red')
                plt.xlim([ymin, ymax])
                plt.ylim([xmin, xmax])
                plt.savefig('test_%d.png' % jj)
                plt.close()

                fig, axs = plt.subplots(1, 2)
                plt.axes(axs[0])
                plt.imshow(image.T,
                           origin='lower',
                           cmap='viridis',
                           aspect=1,
                           interpolation='nearest',
                           vmin=np.percentile(image[image > 0], 10),
                           vmax=np.percentile(image[image > 0], 90))
                apertures.plot(color='red')
                plt.xlim([ymin_f, ymax_f])
                plt.ylim([xmin_f, xmax_f])

                resimage = phot_obj.get_residual_image()
                plt.axes(axs[1])
                plt.imshow(resimage.T,
                           origin='lower',
                           cmap='viridis',
                           aspect=1,
                           interpolation='nearest',
                           vmin=np.percentile(resimage[resimage > 0], 10),
                           vmax=np.percentile(resimage[resimage > 0], 90))
                apertures.plot(color='red')
                plt.xlim([ymin_f, ymax_f])
                plt.ylim([xmin_f, xmax_f])
                plt.savefig('test_f_%d.png' % jj)
                plt.close()

            #phot_results.pprint_all()

            #print(stop)

            dist = np.sqrt((phot_results["x_fit"] - x0)**2 +
                           (phot_results["y_fit"] - y0)**2)
            idx = np.argmin(dist)
            flux = phot_results[idx]["flux_fit"]
            fluxerr = phot_results[idx]["flux_unc"]
            magerr = 1.0857 * fluxerr / flux  #1.0857 = 2.5/log(10)
            mag = zp - 2.5 * np.log10(flux)

            if doDifferential:
                dist = np.sqrt((phot_results["x_fit"] - xfield)**2 +
                               (phot_results["y_fit"] - yfield)**2)
                idy = np.argmin(dist)
                flux_field = phot_results[idy]["flux_fit"]
                fluxerr_field = phot_results[idy]["flux_unc"]
                magerr_field = 1.0857 * fluxerr_field / flux_field  #1.0857 = 2.5/log(10)
                mag_field = zp - 2.5 * np.log10(flux_field)

                mag = mag - mag_field
                magerr = np.sqrt(magerr**2 + magerr_field**2)
                fluxerr = np.sqrt((fluxerr / flux)**2 +
                                  (fluxerr_field / flux_field)**2)
                flux = flux / flux_field
                fluxerr = flux * fluxerr

            #print(phot_results[idy]["flux_fit"], phot_results[idx]["flux_fit"])

            mjds.append(mjd)
            mags.append(mag)
            magerrs.append(magerr)
            fluxes.append(flux)
            fluxerrs.append(fluxerr)

            fid.write('%.5f %.5f %.5f %.5f %.5f\n' %
                      (dateobs.mjd, mag, magerr, flux, fluxerr))
        fid.close()

        return np.array(mjds), np.array(mags), np.array(magerrs), np.array(
            fluxes), np.array(fluxerrs)

    else:
        mjds, mags, magerrs, fluxes, fluxerrs = [], [], [], [], []
        for ii, hdu in enumerate(hdulist):
            if ii == 0: continue
            header = hdulist[ii].header
            image = hdulist[ii].data
            if not "DATE" in header:
                print("Warning: 'DATE missing from %s hdu %d/%d" %
                      (imagefile, ii, len(hdulist)))
                continue

            dateobs = Time(header["DATE"])

            phot_results = phot_obj(image)

            dist = np.sqrt((phot_results["x_fit"] - x0)**2 +
                           (phot_results["y_fit"] - y0)**2)
            idx = np.argmin(dist)
            flux = phot_results[idx]["flux_fit"]
            fluxerr = phot_results[idx]["flux_unc"]
            magerr = 1.0857 * fluxerr / flux  #1.0857 = 2.5/log(10)
            mag = zp - 2.5 * np.log10(flux)

            mjds.append(dateobs.mjd)
            mags.append(mag)
            magerrs.append(magerr)
            fluxes.append(flux)
            fluxerrs.append(fluxerr)

            fid.write('%.5f %.5f %.5f %.5f %.5f\n' %
                      (dateobs.mjd, mag, magerr, flux, fluxerr))
        fid.close()

        return np.array(mjds), np.array(mags), np.array(magerrs), np.array(
            fluxes), np.array(fluxerrs)
    nrc.detector = 'NRCB5'
else:
    nrc.detector = hdu[0].header['DETECTOR']  #'NRCA3'
#nrc_grid = nrc.psf_grid(num_psfs=9, all_detectors=False)
nrc_grid = nrc.psf_grid(num_psfs=25,
                        all_detectors=False,
                        fov_pixels=33,
                        oversample=2)

eval_xshape = int(np.ceil(nrc_grid.data.shape[2] / nrc_grid.oversampling))
eval_yshape = int(np.ceil(nrc_grid.data.shape[1] / nrc_grid.oversampling))

# And now, let's run the PSF Photometry
sigma_psf = 3.
daogroup = DBSCANGroup(2.0 * sigma_psf * gaussian_sigma_to_fwhm)
mmm_bkg = MMMBackground()
fit_shape = (eval_yshape, eval_xshape)
phot = BasicPSFPhotometry(daogroup,
                          mmm_bkg,
                          nrc_grid,
                          fit_shape,
                          finder=None,
                          aperture_radius=3.)

# This is the part that takes the longest, so I print out the date/time before and after.
now = datetime.now()
dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
print("Starting the fit: date and time = ", dt_string)

tbl = phot(data, init_guesses=init_tbl)
예제 #10
0
def bkg(flux, sigma=2.5):
    # Returns background for a single cadence. Default sigma=2.5
    sigma_clip = SigmaClip(sigma=sigma)
    bkg = MMMBackground(sigma_clip=sigma_clip)
    return bkg.calc_background(flux)
예제 #11
0
dec    = float(target[0]['dec'])
coord  = SkyCoord(ra, dec, unit='deg')



ahdu = search_tesscut(coord, sector=args.Sector).download(cutout_size=args.size, download_dir='.')
#w    = WCS(allhdus.hdu[2].header)
hdu  = ahdu.hdu

flux = hdu[1].data['FLUX']
bkgs = np.zeros(len(flux))

#Background
for i,f in enumerate(flux):
    sigma_clip = SigmaClip(sigma=3)
    bkg        = MMMBackground(sigma_clip=sigma_clip)
    bkgs[i]    = bkg.calc_background(f)


#flux = np.log10(np.abs(np.nanmin(flux)) + flux + 1)
time = hdu[1].data['TIME'] + hdu[1].header['BJDREFI']

def animate(i, fig, ax, flux, time, start=0):
    #ax.text(0.98, 0.98, time[i], transform=ax.transAxes, color='white', ha='right', va='top')
    #im = ax.matshow(flux[i+start], cmap=plt.cm.YlGnBu_r)
    im.set_array(flux[i+start])
    te.set_text('%.4f' % time[i+start])
    return im, te

fig, ax = plt.subplots(figsize=[2,2])
ax.set_xticks([])
img_tight, table = read_or_generate_image('tight8group', recipe=recipe)

guess_table_tight = prepare_table(table)

fit_stages_tight = [FitStage(10, 0.001, 0.001, np.inf, all_individual), # first stage: flux is wildly off, get decent guess
              FitStage(10, 2., 2., 50_000, all_individual),
              FitStage(10, 1., 1., 20_000, brightest_simultaneous(3)),
              FitStage(10, 1., 1., 20_000, brightest_simultaneous(5)),
              FitStage(10, 0.5, 0.5, np.inf, all_simultaneous),
              FitStage(50, 0.2, 0.2, 10_000, all_simultaneous)
              ]


# %%
photometry_tight = IncrementalFitPhotometry(MMMBackground(),
                                      model,
                                      max_group_size=100,
                                      group_extension_radius=10,
                                      fit_stages=fit_stages_tight)

result_table_tight = photometry_tight.do_photometry(img_tight, guess_table_tight)

# %%
figure()
residual = photometry_tight.residual(result_table_tight)
imshow(residual[400:600,400:600])
colorbar()
np.max(img_tight)

# %%
def psf_fit(data_array, data_file, psf_grid, fheader, imagemodel):

    # Let's run a quick fitting using DAOStarFinder
    mean, median, std = sigma_clipped_stats(data_array, sigma=3.0)
    daofind = DAOStarFinder(fwhm=3.0, threshold=5. * std)
    sources = daofind(data_array - median)

    # And now, let's make some cuts to remove objects that are too faint or too bright
    flux_min = 5  #5 #0
    flux_max = 50  #50 #1000
    flux_range = np.where((sources['flux'] > flux_min)
                          & (sources['flux'] < flux_max))[0]

    init_tbl = Table()
    init_tbl['x_0'] = sources['xcentroid'][flux_range]
    init_tbl['y_0'] = sources['ycentroid'][flux_range]
    init_tbl['flux_0'] = sources['flux'][flux_range]

    # And now, let's make a plot of the original image.
    plt.figure(figsize=(9, 9))
    imshow_norm(data_array,
                interval=PercentileInterval(99.),
                stretch=SqrtStretch())
    plt.colorbar()
    plt.savefig(data_file + '.png', dpi=300)
    plt.clf()

    # And now, let's make a plot of the image showing the positions of the objects.
    plt.figure(figsize=(9, 9))
    imshow_norm(data_array,
                interval=PercentileInterval(99.),
                stretch=SqrtStretch())
    plt.scatter(init_tbl['x_0'], init_tbl['y_0'], s=10, color='black')
    plt.colorbar()
    plt.savefig(data_file + '_with_daostarfinder_objects.png', dpi=300)
    plt.clf()

    eval_xshape = int(np.ceil(psf_grid.data.shape[2] / psf_grid.oversampling))
    eval_yshape = int(np.ceil(psf_grid.data.shape[1] / psf_grid.oversampling))

    # And now, let's run the PSF Photometry
    sigma_psf = 3.
    daogroup = DBSCANGroup(2.0 * sigma_psf * gaussian_sigma_to_fwhm)
    mmm_bkg = MMMBackground()
    fit_shape = (eval_yshape, eval_xshape)
    phot = BasicPSFPhotometry(daogroup,
                              mmm_bkg,
                              psf_grid,
                              fit_shape,
                              finder=None,
                              aperture_radius=3.)

    # This is the part that takes the longest, so I print out the date/time before and after.
    now = datetime.now()
    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
    print("Starting the fit: date and time = ", dt_string)

    tbl = phot(data_array, init_guesses=init_tbl)

    now = datetime.now()
    dt_string = now.strftime("%d/%m/%Y %H:%M:%S")
    print("Ending the fit: date and time = ", dt_string)

    # Now I format the output
    tbl['x_fit'].format = '%.1f'
    tbl['y_fit'].format = '%.1f'
    tbl['flux_fit'].format = '%.4e'
    tbl['flux_unc'].format = '%.4e'
    tbl['x_0_unc'].format = '%.4e'
    tbl['y_0_unc'].format = '%.4e'

    diff = phot.get_residual_image()
    hdu_out = fits.PrimaryHDU(diff, header=fheader)
    hdul_out = fits.HDUList([hdu_out])
    hdul_out.writeto(data_file + '_residual.fits')

    # And create a residual image from the fit
    plt.figure(figsize=(9, 9))
    imshow_norm(diff, interval=PercentileInterval(99.), stretch=SqrtStretch())
    #plt.scatter(tbl['x_fit'], tbl['y_fit'], s=80, facecolors='none', edgecolors='r')
    plt.colorbar()
    plt.savefig(data_file + '_residual.png', dpi=300)
    plt.clf()

    # Calculate the RA and DEC values from the x_fit and y_fit values.
    RA_fit = np.zeros(len(tbl['x_fit']))
    DEC_fit = np.zeros(len(tbl['x_fit']))
    RA_fit, DEC_fit = imagemodel.meta.wcs(tbl['x_fit'], tbl['y_fit'])

    tbl.add_column(DEC_fit, index=0, name='DEC_fit')
    tbl.add_column(RA_fit, index=0, name='RA_fit')

    # And write out the table to a file.
    tbl.write(data_file + '_psf_fit_output.fits')
예제 #14
0
def img_measure_background(img, use_sep=True, **kwargs):
    """Estimate sky background of an image.

    For SEP, available parameters are:

        sep_kwargs = {'mask': None,
                      'bw': 20, 'bh': 20, 'fw': 3, 'fh':3, }

    For Photutils, available parameters are:

        phot_kwargs = {'bkg': 'median', 'rms': 'mad', 'mask': None,
                       'clip': True, 'sigma': 3.0, 'iters': 10,
                       'bw': 20, 'bh': 20, 'fw': 3, 'fh':3, }
    """
    if use_sep:
        # Use SEP for background
        sep_back = sep.Background(img, **kwargs)
        return sep_back.back(), sep_back.rms()
    else:
        # Use the photutils.background instead
        if _check_kwargs(kwargs, 'clip', True):
            sigma_clip = SigmaClip(sigma=_check_kwargs(kwargs, 'sigma', 3.0),
                                   iters=_check_kwargs(kwargs, 'iters', 3))
        else:
            sigma_clip = None

        bkg = _check_kwargs(kwargs, 'bkg', 'sextractor')
        rms = _check_kwargs(kwargs, 'rms', 'biweight')

        if bkg == 'biweight':
            from photutils import BiweightLocationBackground
            bkg_estimator = BiweightLocationBackground()
        elif bkg == 'sextractor':
            from photutils import SExtractorBackground
            bkg_estimator = SExtractorBackground()
        elif bkg == 'mmm':
            from photutils import MMMBackground
            bkg_estimator = MMMBackground()
        elif bkg == 'median':
            from photutils import MedianBackground
            bkg_estimator = MedianBackground()
        else:
            raise Exception("# Wrong choice of background estimator!")

        if rms == 'biweight':
            from photutils import BiweightScaleBackgroundRMS
            rms_estimator = BiweightScaleBackgroundRMS()
        elif rms == 'mad':
            from photutils import MADStdBackgroundRMS
            rms_estimator = MADStdBackgroundRMS()
        elif rms == 'std':
            from photutils import StdBackgroundRMS
            rms_estimator = StdBackgroundRMS()
        else:
            raise Exception("# Wrong choice of RMS estimator!")

        bw = kwargs['bw'] if ('bw' in kwargs) else 3
        bh = kwargs['bh'] if ('bh' in kwargs) else 3
        fw = kwargs['fw'] if ('fw' in kwargs) else 3
        fh = kwargs['fh'] if ('fh' in kwargs) else 3

        bkg = Background2D(img, (_check_kwargs(
            kwargs, 'bh', 100), _check_kwargs(kwargs, 'bw', 100)),
                           filter_size=(_check_kwargs(kwargs, 'fh', 3),
                                        _check_kwargs(kwargs, 'fw', 3)),
                           mask=_check_kwargs(kwargs, 'mask', None),
                           sigma_clip=sigma_clip,
                           bkg_estimator=bkg_estimator,
                           bkgrms_estimator=rms_estimator)

        return bkg.background, bkg.background_rms
예제 #15
0
fwhm = sigma_psf * gaussian_sigma_to_fwhm
#sigma=fwhm/gaussian_sigma_to_fwhm
# sigma=fwhm/(2.0*np.sqrt(2.0*np.log10(2.0)))????

# group_maker
from photutils.psf import DAOGroup
daogroup = DAOGroup(2.0 * fwhm)

fitsfile = '3C345-20190714@135841-R_Astrodon_2018_calib.fits'
hdu = fits.open(fitsfile)
imhead = hdu[0].header
imdata = hdu[0].data

# bkg_estimator
from photutils import MMMBackground
bkg_estimator = MMMBackground()
from photutils.background import MADStdBackgroundRMS
bkgrms = MADStdBackgroundRMS()
std = bkgrms(imdata)  # error
threshold = 3.5 * std

# background level and error
from astropy.stats import sigma_clipped_stats
mean, median, std = sigma_clipped_stats(imdata, sigma=3.)
# print(mean,median,std)
# 1176.6646745343921 1176.0827349796416 39.1334108277639

# fitter
from astropy.modeling.fitting import LevMarLSQFitter
fitter = LevMarLSQFitter()