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
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)
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
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)
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
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
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
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)
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)
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')
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
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()