PSFs and defocus

The three focus modes

The WCC observes both in focus and deliberately defocused (to average over pixel-level systematics for bright stars). wcc-sim supports three modes, selected with focus=:

focus

PSF

Source

0

In-focus Airy pattern

Analytic (wcc_etc.AiryPSF)

1

+1 wave of defocus

Zemax Huygens PSF data bundled with wcc_etc

2

+2 waves of defocus

Zemax Huygens PSF data bundled with wcc_etc

If focus=None (the default), the focus level implied by the sensorfilter key is used — e.g. zwo:r+1 defaults to 1 wave, zwo:r to in-focus.

The defocused PSFs are annular: the core is centrally depressed and most of the energy lands in a ring (radius ~29 px for 2 waves on the IMX455). This has consequences for saturation flagging (see Noise and saturation).

Oversampled rendering

Stars land at arbitrary sub-pixel positions, so the PSF is rendered once on a fine grid and shifted per star:

  1. render_oversampled_psf() asks wcc_etc to render the PSF on a grid oversampled 11× relative to the detector (by describing a detector with 11× smaller pixels to the PSF context). Jitter blur is applied by wcc_etc at the fine plate scale.

  2. add_star() shifts the fine-grid stamp by the star’s sub-pixel offset (an np.roll, exact to 1/22 px) and bins 11×11 fine pixels into each detector pixel.

Stamp sizes

Stamps are square with an odd number of detector pixels, set by wcc_sim.psf.DEFAULT_STAMP:

focus

Stamp [px]

Rationale

0

129

Holds ≥ 99.5 % of the jitter-blurred Airy energy (65 px would truncate ~1.3 % in the wings).

1, 2

257

The Zemax Huygens defocus data spans ~272 IMX455 px.

Override with stamp_npix= (odd) to trade wing fidelity for speed, and oversample= to change the sub-pixel resolution.

Jitter

Pointing jitter is modeled as a Gaussian blur of the PSF. By default the telescope’s configured jitter (from the wcc_etc telescope model) is used; override per-simulation with jitter_sigma_mas=. The value actually used is recorded in field.params["jitter_sigma_mas"] and the JITTER header card.

from wcc_sim.detectors import make_base_simulation
from wcc_sim.psf import render_oversampled_psf

sim = make_base_simulation("zwo:r")
psf0 = render_oversampled_psf(sim, focus=0)                      # Airy
psf2 = render_oversampled_psf(sim, focus=2, jitter_sigma_mas=50) # defocus + jitter

Both return a normalized 2-D array on the fine grid (sum = 1), ready for render_scene().