def epsf_from_model(input_model,
                    n_images,
                    stars_per_image,
                    fitshape,
                    oversampling=1,
                    σ=0,
                    λ=None,
                    smoothing='quartic',
                    epsf_iters=5,
                    seed=0):

    size = 128 * int(np.ceil(np.sqrt(stars_per_image)))
    border = 32
    rng = np.random.default_rng(seed)
    stars = []
    for i in range(n_images):
        img, xy_list = gen_image(input_model, stars_per_image, size, border,
                                 'random', σ, λ, rng)

        stars += list(
            extract_stars(NDData(img),
                          Table(xy_list, names=['x', 'y']),
                          size=np.array(fitshape)))

    stars = EPSFStars(stars)
    builder = EPSFBuilder(oversampling=oversampling,
                          smoothing_kernel=smoothing,
                          maxiters=epsf_iters)

    epsf, fitted_stars = builder(stars)
    return epsf, reference_image(input_model, fitshape, oversampling)
Exemple #2
0
def extract_epsf_stars(image: np.ndarray, image_stats: ImageStats,
                       stars_tbl: InputTable, config: Config) -> EPSFStars:
    image_no_background = image - image_stats.median

    stars_tbl_filtered = stars_tbl[
        stars_tbl[INPUT_TABLE_NAMES[FLUX]] < config.detector_saturation]
    stars_tbl_filtered.sort(INPUT_TABLE_NAMES[FLUX], reverse=True)
    stars = extract_stars(NDData(image_no_background),
                          stars_tbl_filtered,
                          size=config.cutout_size)
    if len(stars) == 0:
        warnings.warn('No stars extracted')
    return stars[:config.max_epsf_stars]
Exemple #3
0
recipe_group = lambda:\
    generators.scopesim_groups(N1d=1,
                               jitter=8.,
                               border=400,
                               magnitude=lambda N: np.random.normal(19, 1.5, N),
                               group_size=9,
                               group_radius=7
                               )

img, input_table = generators.read_or_generate_image(recipe_group, name_group)

sigma_clipped_stats(img)
grid_img_no_background = img_grid - np.median(img_grid)


stars = extract_stars(NDData(grid_img_no_background), input_table_grid, size=cutout_size)

epsf, _ = EPSFBuilder(oversampling=2,
                      maxiters=6,
                      progress_bar=True,
                      smoothing_kernel=util.make_gauss_kernel(0.5)).build_epsf(stars)

mean, median, std = sigma_clipped_stats(img)

grouper = DAOGroup(60)
finder = DAOStarFinder(threshold=median-2*std, fwhm=2.)

phot = BasicPSFPhotometry(grouper, MADStdBackgroundRMS(), epsf, cutout_size+2, finder=finder)
phot_nogroup = BasicPSFPhotometry(DAOGroup(0.001), MADStdBackgroundRMS(), epsf, cutout_size+2, finder=finder)

init_guess = input_table.copy()
Exemple #4
0
img_grid, tab_grid = read_or_generate_image(
    'scopesim_grid_16_perturb2_mag18_24_subpixel')

epsf_sources = tab_grid.copy()
epsf_sources = epsf_sources[(epsf_sources['m'] > 19.5)
                            & ((1024 - 100) > epsf_sources['x']) &
                            (epsf_sources['x'] > 100)
                            & ((1024 - 100) > epsf_sources['y']) &
                            (epsf_sources['y'] > 100)]
epsf_sources.sort('m', reverse=False)

fitshape = 41

epsf_stars = extract_stars(NDData(img_grid),
                           epsf_sources[:100],
                           size=(fitshape + 2, fitshape + 2))
builder = EPSFBuilder(oversampling=4,
                      smoothing_kernel=make_gauss_kernel(2.3, N=21),
                      maxiters=5)
pre_epsf, _ = cached(lambda: builder.build_epsf(epsf_stars),
                     cache_dir / 'epsf_synthetic',
                     rerun=False)
data = pre_epsf.data[9:-9, 9:-9].copy()
data /= np.sum(data) / np.sum(pre_epsf.oversampling)
epsf = FittableImageModel(data=data, oversampling=pre_epsf.oversampling)
epsf.origin = centroid_quadratic(epsf.data)


def grid_photometry_epsf():
    fit_stages_grid = [
saturation_model = SaturationModel(
    read_scopesim_linearity(Config.instance().scopesim_working_dir /
                            'inst_pkgs/MICADO/FPA_linearity.dat'))
img = saturation_model.inverse_eval(img)

mean, median, std = sigma_clipped_stats(img)

finder = DAOStarFinder(threshold=median - 5 * std, fwhm=3.5, sigma_radius=2.7)

image_no_background = img - median
all_stars = finder(img)

stars_tbl = all_stars.copy()
stars_tbl.rename_columns(['xcentroid', 'ycentroid'], ['x', 'y'])

stars = extract_stars(NDData(image_no_background), stars_tbl[:300], size=11)

epsf, fitted_stars = EPSFBuilder(
    oversampling=2,
    maxiters=6,
    progress_bar=True,
    smoothing_kernel=util.make_gauss_kernel(0.45)).build_epsf(stars)

culled = CorrelationCuller(100, image_no_background, epsf)(all_stars)

sorted_stars = all_stars.copy()
sorted_stars.rename_columns(['xcentroid', 'ycentroid'], ['x', 'y'])
sorted_stars['qof'] = sorted_stars['model_chisquare'] / sorted_stars['flux']
sorted_stars.sort('qof')

stars_refined = extract_stars(NDData(image_no_background),
Exemple #6
0
def naco_astrometry(image,
                    input_psf,
                    offset,
                    reference_table,
                    use_reference=False,
                    use_psf=False):

    fwhm = estimate_fwhm(input_psf.psfmodel)
    mean, median, std = sigma_clipped_stats(image)
    # todo make configurable
    #  values here are handfudged to get maximum amount of candidates
    #  ommitted peakmax = 10_000

    finder = phot.IRAFStarFinder(threshold=median * threshold_factor,
                                 fwhm=fwhm * fwhm_factor,
                                 brightest=n_brightest,
                                 minsep_fwhm=minsep_fwhm,
                                 peakmax=peakmax)

    if np.all(np.isnan(image)):
        return Table()

    if use_reference:
        stars_tbl = reference_table.copy()
        stars_tbl.rename_columns(['XRAW', 'YRAW'], ['x', 'y'])
        stars_tbl['x'] -= offset[0]
        stars_tbl['y'] -= offset[1]
        cut_x = (stars_tbl['x'] >= 0) & (stars_tbl['x'] <= image.shape[1])
        cut_y = (stars_tbl['y'] >= 0) & (stars_tbl['y'] <= image.shape[0])
        stars_tbl = stars_tbl[cut_x & cut_y]
    else:
        stars_tbl = finder(image)
        stars_tbl.rename_columns(['xcentroid', 'ycentroid'], ['x', 'y'])

    if use_psf:
        psf = input_psf
    else:
        image_no_background = image - median
        stars = phot.extract_stars(NDData(image_no_background),
                                   stars_tbl,
                                   size=cutout_size)
        epsf, fitted_stars = phot.EPSFBuilder(
            oversampling=oversampling,
            maxiters=epsf_iters,
            progress_bar=True,
            smoothing_kernel=smoothing_kernel).build_epsf(stars)
        psf = phot.prepare_psf_model(epsf, renormalize_psf=False)

    grouper = phot.DAOGroup(group_radius * fwhm)

    if use_reference:
        photometry = phot.BasicPSFPhotometry(
            group_maker=grouper,
            finder=finder,
            bkg_estimator=phot.MMMBackground(),
            aperture_radius=fwhm,
            fitshape=fitshape,
            psf_model=psf)
        stars_tbl.rename_columns(['x', 'y'], ['x_0', 'y_0'])
        size = len(stars_tbl)
        stars_tbl['x_0'] += np.random.uniform(
            0.1, 0.2, size) * np.random.choice([-1, 1], size)
        stars_tbl['y_0'] += np.random.uniform(
            0.1, 0.2, size) * np.random.choice([-1, 1], size)
        result = photometry(image, init_guesses=stars_tbl)
    else:
        photometry = phot.IterativelySubtractedPSFPhotometry(
            group_maker=grouper,
            finder=finder,
            bkg_estimator=phot.MMMBackground(),
            aperture_radius=fwhm,
            fitshape=fitshape,
            psf_model=psf,
            niters=photometry_iters)

        result = photometry(image)

    result['x_fit'] += offset[0]
    result['y_fit'] += offset[1]

    return result
def astrometry(image: np.ndarray,
               reference_table: Optional[Table] = None,
               known_psf: Optional[photutils.EPSFModel] = None):
    """
    All the steps necessary to do basic PSF astrometry with photutils
    :param image:
    :param reference_table:
    :param known_psf:
    :return:
    """
    if known_psf:
        fwhm = estimate_fwhm(known_psf)
    else:
        fwhm = fwhm_guess

    # get image stats and build finder
    mean, median, std = sigma_clipped_stats(image)
    finder = photutils.DAOStarFinder(threshold=median * threshold_factor,
                                     fwhm=fwhm * fwhm_factor,
                                     sigma_radius=sigma_radius,
                                     brightest=n_brightest,
                                     peakmax=peakmax)

    if reference_table:
        stars_tbl = reference_table.copy()
    else:
        stars_tbl = finder(image)
        stars_tbl.rename_columns(['xcentroid', 'ycentroid'], ['x', 'y'])

    # extract star cutouts and fit EPSF from them
    image_no_background = image - median
    stars = photutils.extract_stars(NDData(image_no_background), stars_tbl, size=cutout_size)
    epsf, fitted_stars = photutils.EPSFBuilder(oversampling=oversampling,
                                               maxiters=epsf_iters,
                                               progress_bar=True,
                                               smoothing_kernel=smoothing_kernel).build_epsf(stars)
    # renormalization is probably important if fluxes are interesting, for positions it does not seem to matter
    psf = photutils.prepare_psf_model(epsf, renormalize_psf=False)

    grouper = photutils.DAOGroup(group_radius * fwhm)

    if reference_table:
        photometry = photutils.BasicPSFPhotometry(
            group_maker=grouper,
            finder=None,
            bkg_estimator=photutils.MMMBackground(),  # Don't really know what kind of background estimator is preferred
            aperture_radius=fwhm,
            fitshape=fitshape,
            psf_model=psf)
        stars_tbl.rename_columns(['x', 'y'], ['x_0', 'y_0'])
        size = len(stars_tbl)
        # randomly perturb guesses to make fit do something
        stars_tbl['x_0'] += np.random.uniform(0.1, 0.2, size) * np.random.choice([-1, 1], size)
        stars_tbl['y_0'] += np.random.uniform(0.1, 0.2, size) * np.random.choice([-1, 1], size)

        result = photometry(image, init_guesses=stars_tbl)
    else:
        # it might be a good idea to build another finder/grouper here based on the derived EPSF
        photometry = photutils.IterativelySubtractedPSFPhotometry(
            group_maker=grouper,
            finder=finder,
            bkg_estimator=photutils.MMMBackground(),
            aperture_radius=fwhm,
            fitshape=fitshape,
            psf_model=psf,
            niters=photometry_iters
        )

        result = photometry(image)

    return result
Exemple #8
0
                             peakmax=10_000,
                             exclude_border=True,
                             brightest=300)
epsf_sources = epsf_finder(img_combined)

# %%
plt.figure()
plt.imshow(img_combined, norm=LogNorm())
plt.plot(epsf_sources['xcentroid'], epsf_sources['ycentroid'], 'rx')

# %%
epsf_sources['x'] = epsf_sources['xcentroid']
epsf_sources['y'] = epsf_sources['ycentroid']

epsf_stars = extract_stars(NDData(img_combined),
                           epsf_sources,
                           size=(fitshape + 2, fitshape + 2))
builder = EPSFBuilder(oversampling=2, smoothing_kernel='quadratic', maxiters=7)
initial_epsf, _ = cached(lambda: builder.build_epsf(epsf_stars),
                         cache_dir / 'initial_epsf_naco')

# %%
plt.figure()
plt.imshow(initial_epsf.data, norm=LogNorm())

# %%
y, x = np.mgrid[-fitshape / 2:fitshape / 2:1j * fitshape,
                -fitshape / 2:fitshape / 2:1j * fitshape]
psffind = StarFinder(threshold=10,
                     kernel=initial_epsf(x, y),
                     min_separation=20,
Exemple #9
0
        residual -= fitted_model(x,y)
        #fitted_models.append(fitted_model)
    return residual


def normalize(img):
    return img-img.min()+1


if __name__ == "__main__":
    img_conv, input_table_conv = convolved_grid(N1d=5, border=100, perturbation=2., kernel=Gaussian2DKernel(x_stddev=10, y_stddev=12, x_size=101, y_size=101), seed=1327)
    img_conv -= 0.00
    img_mod, input_table_mod = model_add_grid(gauss2d(σ_x=10., σ_y=12), N1d=5, border=100, perturbation=2., seed=1327)

    cutout_size = 181
    stars_mod = extract_stars(NDData(img_mod), input_table_mod, size=(cutout_size, cutout_size))
    stars_conv = extract_stars(NDData(img_conv), input_table_mod, size=(cutout_size, cutout_size))

    epsf_analytic = Gaussian2D()

    epsf_fit_mod = EPSFBuilder(maxiters=8, oversampling=2, smoothing_kernel='quadratic').build_epsf(stars_mod)
    epsf_fit_conv = EPSFBuilder(maxiters=8, oversampling=2, smoothing_kernel='quadratic').build_epsf(stars_conv)


    detections = np.array((input_table_mod['x'], input_table_mod['y'])).T



    residual_ana_mod = compute_residual(img_mod, epsf_analytic)
    residual_ana_conv = compute_residual(img_conv, epsf_analytic)
    residual_epsf_mod = compute_residual(img_mod, epsf_fit_mod)