Shack-Hartmann WFS

Overview

The ShackHartmann class implements a Shack-Hartmann Wavefront Sensor (SH-WFS). A lenslet array placed at the pupil plane focuses light from each subaperture onto a detector. The WFS signals are derived from the intensity distribution of the spots across the detector.

Two computation modes are available:

  • Diffractive (default) — each subaperture spot is computed via FFT, correctly modelling diffraction and LGS elongation effects.

  • Geometric — direct computation from the phase; faster but ignores diffraction.

Key concepts

  • nSubap — number of lenslets across the pupil diameter. Defines the measurement grid.

  • lightRatio — minimum illumination fraction to mark a subaperture as valid.

  • pixel_scale — angular size of each detector pixel in arcseconds. If not set, defaults to Shannon sampling (2 pixels per FWHM) or 1 pixel per FWHM.

  • Detector — the SH-WFS has a built-in Detector (wfs.cam) supporting all noise and binning models.

  • em_field_transform — an optional FieldTransformer applied to the EM field before propagation through the lenslet array, used for example to apply sub-pixel shifts for super-resolution.

Quick start

from OOPAO.ShackHartmann import ShackHartmann

wfs = ShackHartmann(
    nSubap       = 20,
    telescope    = tel,
    lightRatio   = 0.5,
)

# Propagate light
ngs * tel * wfs

print(wfs.signal)          # 1-D WFS signal vector
print(wfs.signal_2D)       # 2-D representation of WFS signals
print(wfs.cam.frame)       # raw detector frame

# Geometric mode (faster)
wfs.is_geometric = True
ngs * tel * wfs

API reference

class OOPAO.ShackHartmann.ShackHartmann(nSubap, telescope, lightRatio, threshold_cog=0.01, is_geometric=False, binning_factor=1, pixel_scale=None, threshold_convolution=0.05, shannon_sampling=False, n_pixel_per_subaperture=None, half_pixel_shift=False, em_field_transform=None)[source]

Shack-Hartmann Wavefront Sensor (diffractive or geometric).

Parameters:
  • nSubap (int) – Number of lenslets across the pupil diameter.

  • telescope (Telescope) – Telescope object carrying phase, flux, and pupil information.

  • lightRatio (float) – Minimum fractional flux threshold for valid subaperture selection.

  • threshold_cog (float) – Relative threshold (fraction of peak) applied before computing the centre of gravity. Default 0.01.

  • is_geometric (bool) – If True, use the geometric WFS (direct gradient). If False (default), use the diffractive model.

  • binning_factor (int) – Detector binning factor. Default 1.

  • pixel_scale (float or None) – Desired pixel scale in arcseconds. The nearest realisable scale (given FFT sampling) is used. Default None (Shannon sampling).

  • threshold_convolution (float) – Relative threshold applied to Gaussian LGS spot model to suppress edge effects. Default 0.05.

  • shannon_sampling (bool) – If True and pixel_scale=None, uses 2 pix/FWHM. If False (default), uses 1 pix/FWHM.

  • n_pixel_per_subaperture (int or None) – Number of pixels per subaperture. If smaller than the FFT-native value, subapertures are cropped; if larger, zero-padded (a warning is shown). Default None (native).

  • half_pixel_shift (bool) – If True, applies a half-pixel focal-plane shift to centre spots on 1 pixel. Default False (spots centred on 4 pixels).

  • em_field_transform (FieldTransformer or None) – A FieldTransformer instance applied to the source EM field before propagation through the lenslet array. Used for example to introduce sub-pixel shifts for super-resolution. Default None.

Key properties

signal: numpy.ndarray

1-D WFS signal vector for all valid subapertures.

signal_2D: numpy.ndarray

2-D representation of the WFS signals.

valid_signal_2D: numpy.ndarray

2-D layout of the valid WFS signal pixels on the detector.

nSignal: int

Total length of the signal vector.

valid_subapertures: numpy.ndarray

2-D boolean mask of valid subapertures over the pupil grid.

valid_subapertures_1D: numpy.ndarray

Flattened 1-D boolean version of valid_subapertures.

nValidSubap: int

Number of valid (illuminated) subapertures.

cam: Detector

Built-in detector. Set cam.photonNoise, cam.readoutNoise, etc. to simulate detector effects.

is_geometric: bool

Switch between diffractive (False) and geometric (True) computation modes at runtime.

pixel_scale: float

Effective pixel scale in arcseconds (read-only after initialisation).

n_pix_subap: int

Number of pixels per subaperture on the detector.

Methods

relay(src)[source]

Core propagation method. Called automatically by src * wfs. Computes the spot images for each subaperture and derives the WFS signals.

Parameters:

src (Source or Asterism) – Source or Asterism being propagated.

set_weighted_centroiding_map(weight_map)[source]

Set a custom 2-D centroiding weight map for the spots. Recalibrates signal units afterwards.

Parameters:

weight_map (numpy.ndarray) – 2-D weight array of shape (n_pix_subap, n_pix_subap).

set_slopes_units()[source]

Recalibrate the signal unit conversion factor (called automatically after set_weighted_centroiding_map()).

Operator summary

Expression

Effect

ngs * tel * wfs

Propagate through telescope then SH-WFS

ngs ** atm * tel * wfs

Full reset + atmosphere + telescope + SH-WFS