def _verify_planet_location(data, true_location, true_flux=None, true_fwhm=None, thresholds=None, searchrad=None): """ Helper function to verify the planet how we expect it to look in the data. Only need to pass the true params you want to test (will skip the other ones) Args: data: 2d data with fake planet ot test true_location: [x,y] locaiton where we expect the planet true_flux: expected peak flux of the planet true_fwhm: expected fwhm on the plnaet thresholds: error tresholds. Need to pass all 4 even if not testing all of them format is [xerr, yerr, fluxerr (Fractional), fwhmerr] if None, threshold = [0.001, 0.001, 0.005, 0.05] searchrad: search radius for the fit """ if thresholds is None: thresholds = [0.001, 0.001, 0.005, 0.05] elif np.size(thresholds) != 4: raise ValueError( "thresholds should be a 4 element array but got {0} elements". format(np.size(thresholds))) if searchrad is None: if true_fwhm is not None: searchrad = int(round(true_fwhm)) else: searchrad = 7 rounded_true_location = np.rint(true_location) retrieved_noshift = fakes.gaussfit2d(data, rounded_true_location[0], rounded_true_location[1], searchrad=searchrad) output_noshift_pos = np.array(retrieved_noshift[2:4]) # [x, y] output_noshift_flux = retrieved_noshift[0] output_noshift_fwhm = retrieved_noshift[1] print(retrieved_noshift) # x position should be accurate to < 0.001 pixels assert np.abs(true_location[0] - output_noshift_pos[0]) < thresholds[0] # do the same for y position assert np.abs(true_location[1] - output_noshift_pos[1]) < thresholds[1] if true_flux is not None: # Flux without noise should be accurate to < 0.5% assert np.abs(true_flux - output_noshift_flux) / true_flux < thresholds[2] if true_fwhm is not None: # FWHM should also be accurate to within 0.05 pix assert np.abs(true_fwhm - output_noshift_fwhm) < thresholds[3]
def measure_star_flux(img, star_x, star_y): """ Measure star peak fluxes using a Gaussian matched filter Args: img: 2D frame with unobscured, unsaturated PSF star_x, star_y: coordinates of the star Return: star_f: star flux """ flux, fwhm, xfit, yfit = gaussfit2d(img, star_x, star_y, refinefit=False) if flux == np.inf: flux == np.nan print flux, fwhm, xfit, yfit return flux
def _measure_sat_spots(cube, wvs, guess_spot_index, guess_spot_locs, highpass=True): """ Find sat spots in a datacube. TODO: return sat spot psf cube also """ # use dictionary to store list of locs/fluxes for each slice spot_locs = {} spot_fluxes = {} spot_fwhms = {} # start with guess center start_frame = cube[guess_spot_index] if highpass: start_frame = klip.high_pass_filter(start_frame, 10) start_spot_locs = [] start_spot_fluxes = [] start_spot_fwhms = [] for guess_spot_loc in guess_spot_locs: xguess, yguess = guess_spot_loc fitargs = fakes.gaussfit2d(start_frame, xguess, yguess, refinefit=True, searchrad=6) fitflux, fitfwhm, fitx, fity = fitargs start_spot_locs.append([fitx, fity]) start_spot_fluxes.append(fitflux) start_spot_fwhms.append(fitfwhm) spot_locs[guess_spot_index] = start_spot_locs spot_fluxes[guess_spot_index] = np.nanmean(start_spot_fluxes) spot_fwhms[guess_spot_index] = np.nanmean(start_spot_fwhms) # set this reference center to use for finding the spots at other wavelengths ref_wv = wvs[guess_spot_index] ref_center = np.mean(start_spot_locs, axis=0) ref_spot_locs_deltas = np.array(start_spot_locs) - ref_center[ None, :] # offset from center for i, (frame, wv) in enumerate(zip(cube, wvs)): # we already did the inital index if i == guess_spot_index: continue if highpass: frame = klip.high_pass_filter(frame, 10) # guess where the sat spots are based on the wavelength wv_scaling = wv / ref_wv # shorter wavelengths closer in thiswv_guess_spot_locs = ref_spot_locs_deltas * wv_scaling + ref_center # fit each sat spot now thiswv_spot_locs = [] thiswv_spot_fluxes = [] thiswv_spot_fwhms = [] for guess_spot_loc in thiswv_guess_spot_locs: xguess, yguess = guess_spot_loc fitargs = fakes.gaussfit2d(frame, xguess, yguess, refinefit=True, searchrad=6) fitflux, fitfwhm, fitx, fity = fitargs thiswv_spot_locs.append([fitx, fity]) thiswv_spot_fluxes.append(fitflux) thiswv_spot_fwhms.append(fitfwhm) spot_locs[i] = thiswv_spot_locs spot_fluxes[i] = np.nanmean(thiswv_spot_fluxes) spot_fwhms[i] = np.nanmean(thiswv_spot_fwhms) # turn them into numpy arrays locs = [] fluxes = [] fwhms = [] for i in range(cube.shape[0]): locs.append(spot_locs[i]) fluxes.append(spot_fluxes[i]) fwhms.append(spot_fwhms[i]) return np.array(locs), np.array(fluxes), np.array(fwhms)
with fits.open(f"{datadir}/{unocculted_psf}") as hdulist: psf_cube = hdulist[0].data psf_head = hdulist[0].header if len(psf_cube.shape) == 2: psf_frame = psf_cube elif len(psf_cube.shape) == 3: # Collapse reference psf in time psf_frame = np.nanmean(psf_cube, axis=0) # Find the centroid bestfit = fakes.gaussfit2d(psf_frame, center_x, center_y, searchrad=3, guessfwhm=2, guesspeak=1, refinefit=True) psf_xcen, psf_ycen = bestfit[2:4] peak_flux = bestfit[0] # Recenter PSF to that location x, y = np.meshgrid(np.arange(-20, 20.1, 1), np.arange(-20, 20.1, 1)) x += psf_xcen y += psf_ycen psf_stamp = scipy.ndimage.map_coordinates(psf_frame, [y, x]) norm_contrast = contrast / peak_flux
psfs_centers = [(cent[1], cent[0]) for cent in psfs_centers] psfs_centers = np.array(psfs_centers) center0 = np.median(psfs_centers, axis=0) psfs_xcenters = [] psfs_ycenters = [] psfs_stamps_centers = [] psfs_stampcenters = [] star_peaks = [] psf_stamps = np.zeros((nwvs, psf_cube_size, psf_cube_size)) for k, im in enumerate(oripsfs): # print("center",k) corrflux, fwhm, spotx, spoty = gaussfit2d( im, center0[0], center0[1], searchrad=5, guessfwhm=3, guesspeak=np.nanmax(im), refinefit=True) #spotx, spoty = center0 psfs_xcenters.append(spotx) psfs_ycenters.append(spoty) star_peaks.append(corrflux) xarr_spot = int(np.round(np.mean(psfs_xcenters))) yarr_spot = int(np.round(np.mean(psfs_ycenters))) for k, (im, spotx, spoty) in enumerate( zip(oripsfs, psfs_xcenters, psfs_ycenters)): # Get the closest pixel # xarr_spot = int(np.round(spotx)) # yarr_spot = int(np.round(spoty))