Airy PSF utilities (wcc_etc.airy)

wcc_etc.airy.get_airy_psf(D, rr, wavelength, normalize=True)[source]

Unobscured circular-aperture Airy PSF on grid of radial coords rr [rad].

INPUT:

D - diameter in m rr - rad? wavelength - in m

OUTPUT:

EXAMPLE:

psf2d = wcc_etc.airy.airy_psf(D, rr, k) psf2d /= psf2d.sum()

wcc_etc.airy.get_ee_value_at_radius(r_mas, ee, r_value)[source]

Interpolate EE curve to get EE value at a given radius

wcc_etc.airy.gaussian_kernel_2d(sigma_pix, size=None)[source]

Return normalized 2D Gaussian kernel with given sigma in pixels.

INPUT:

sigma_pix - size -

OUTPUT:

kernel -

EXAMPLE:

sigma_pix = sig / px_scale_mean ker = gaussian_kernel_2d(sigma_pix) psf_blur = fftconvolve(psf2d, ker, mode=’same’)

wcc_etc.airy.psf_to_encircled_energy(psf, pixel_scale_x_mas, pixel_scale_y_mas)[source]

Convert a 2D PSF to encircled energy vs radius using annular sums. Allows for possibly non-square images by using separate pixel scales in x and y.

INPUT:

psf - input PSF pixel_scale_x_mas pixel_scale_y_mas

OUTPUT:

r_mas - radii in mas ee - encircled energy

EXAMPLE:

wcc_etc.airy.render_detector_psf(wavelength, fnum, D, pixel_size, jitter_sigma_mas=0, n_pixels=21, oversample=11, verbose=False)[source]

Render the (optionally jittered) Airy PSF onto the detector pixel grid.

The PSF is computed on a grid oversampled by oversample per detector pixel, optionally convolved with a Gaussian jitter kernel, then binned down to detector pixels. The grid uses an odd number of detector pixels so the PSF peak sits on the central pixel (worst case), making the brightest-pixel fraction conservative for a saturation check. The result is normalized so the rendered window sums to 1.

Defocus extension: a defocus kernel can be convolved alongside the jitter kernel at the oversampled stage without changing this function’s interface.

INPUT:

wavelength       - wavelength in m
fnum             - f-number (focal ratio)
D                - primary diameter in m
pixel_size       - detector pixel size in microns
jitter_sigma_mas - jitter sigma in mas (0 = none)
n_pixels         - detector pixels per side (forced odd)
oversample       - Sub-pixel sampling factor per detector pixel. Any value
                   works (centering is by symmetry); odd values place a
                   sample exactly on the PSF peak.
verbose          - print diagnostics

OUTPUT:

psf_detector     - (n_pixels, n_pixels) array summing to 1; its max
                   is the brightest-pixel energy fraction
pscale_mas       - detector plate scale in mas/pixel
wcc_etc.airy.calc_plate_scale_from_flength(focal_length, pix_size)[source]

Calculate the plate scale from the focal length

INPUT:

focal length in m pixel size in microns

OUTPUT:

plate scale in arcsec/pix

NOTES:

focal_length has to be in m pix_size is in microns

wcc_etc.airy.get_airy_and_ee_curve_pixel_grid(wavelength, r_aper_mas, grid_size=100, verbose=False, jitter_sigma_mas=0, plot=False, ax1=None, ax2=None, pixel_size=3.74, fnum=15, D=3)[source]
INPUT:

wavelength - wavelength in m D - diameter in m grid_size - extent_mas -

EXAMPLE:

r_mas, ee_base = get_ee_curve(wavelength=0.6e-6) r_mas, psf1d, ee = wcc_etc.airy.get_airy_and_ee_curve(wavelength=wavelength*1e-6,plot=True,jitter_sigma_mas=JITTER_MAS,ax=ax,r_aper_mas=70)

wcc_etc.airy.get_airy_and_ee_curve(wavelength, r_aper_mas, grid_size=1024, extent_mas=500, verbose=False, jitter_sigma_mas=0, plot=False, ax1=None, ax2=None, pixel_size=3.74, fnum=15, D=3)[source]

Calculate airy curve

INPUT:

wavelength - wavelength in m grid_size - number of pixels in the grid (square) extent_mas - size of the grid in milliarcseconds D - diameter in m

EXAMPLE:

r_mas, ee_base = get_ee_curve(wavelength=0.6e-6) r_mas, psf1d, ee = wcc_etc.airy.get_airy_and_ee_curve(wavelength=wavelength*1e-6,plot=True,jitter_sigma_mas=JITTER_MAS,ax=ax,r_aper_mas=70)

wcc_etc.airy.jittered_ee_list(psf2d, jitter_sigmas_mas, px_scale_x_mas, px_scale_y_mas)[source]

Loop through different PSFs