Wave-front Sensors

WFS Module

The Soapy WFS module.

This module contains a number of classes which simulate different adaptive optics wavefront sensor (WFS) types. All wavefront sensor classes can inherit from the base WFS class. The class provides the methods required to calculate phase over a WFS pointing in a given WFS direction and accounts for Laser Guide Star (LGS) geometry such as cone effect and elongation. This is If only pupil images (or complex amplitudes) are required, then this class can be used stand-alone.

Example

Make configuration objects:

from soapy import WFS, confParse

config = confParse.Configurator("config_file.py")
config.loadSimParams()

Initialise the wave-front sensor:

wfs = WFS.WFS(config, 0 mask)

Set the WFS scrns (these should be made in advance, perhaps by the soapy.atmosphere module). Then run the WFS:

wfs.scrns = phaseScrnList
wfs.makePhase()

Now you can view data from the WFS frame:

frameEField = wfs.EField

A Shack-Hartmann WFS is also included in the module, this contains further methods to make the focal plane, then calculate the slopes to send to the reconstructor.

Example

Using the config objects from above...:

shWfs = WFS.ShackHartmann(config, 0, mask)

As we are using a full WFS with focal plane making methods, the WFS base classes frame method can be used to take a frame from the WFS:

slopes = shWfs.frame(phaseScrnList)

All the data from that WFS frame is available for inspection. For instance, to obtain the electric field across the WFS and the image seen by the WFS detector:

EField = shWfs.EField
wfsDetector = shWfs.wfsDetectorPlane

Adding new WFSs

New WFS classes should inherit the WFS class, then create methods which deal with creating the focal plane and making a measurement from it. To make use of the base-classes frame method, which will run the WFS entirely, the new class must contain the following methods:

calcFocalPlane(self)
makeDetectorPlane(self)
calculateSlopes(self)

The Final calculateSlopes method must set self.slopes to be the measurements made by the WFS. If LGS elongation is to be used for the new WFS, create a detectorPlane, which is added to for each LGS elongation propagation. Have a look at the code for the Shack-Hartmann and experimental Pyramid WFSs to get some ideas on how to do this.

Author:Andrew Reeves

Base WFS Class

class soapy.wfs.base.WFS(soapy_config, n_wfs=0, mask=None)[source]

A WFS class.

This is a base class which contains methods to initialise the WFS, and calculate the phase across the WFSs input aperture, given the WFS guide star geometry.

Parameters:
  • soapy_config (ConfigObj) – The soapy configuration object
  • nWfs (int) – The ID number of this WFS
  • mask (ndarray, optional) – An array or size (simConfig.simSize, simConfig.simSize) which is 1 at the telescope aperture and 0 else-where.
addPhotonNoise()[source]

Add photon noise to wfsDetectorPlane using numpy.random.poisson

addReadNoise()[source]

Adds read noise to wfsDetectorPlane using ``numpy.random.normal. This generates a normal (guassian) distribution of random numbers to add to the detector. Any CCD bias is assumed to have been removed, so the distribution is centred around 0. The width of the distribution is determined by the value eReadNoise set in the WFS configuration.

calcElongPhaseAddition(elongLayer)[source]

Calculates the phase required to emulate layers on an elongated source

For each ‘elongation layer’ a phase addition is calculated which accounts for the difference in height from the nominal GS height where the WFS is focussed, and accounts for the tilt seen if the LGS is launched off-axis.

Parameters:elongLayer (int) – The number of the elongation layer
Returns:The phase addition required for that layer.
Return type:ndarray
calcElongPos(elongLayer)[source]

Calculates the difference in GS position for each elongation layer only makes a difference if LGS launched off-axis

Parameters:elongLayer (int) – which elongation layer
Returns:The effective position of that layer GS on the simulation phase grid
Return type:float
frame(scrns, phase_correction=None, read=True, iMatFrame=False)[source]

Runs one WFS frame

Runs a single frame of the WFS with a given set of phase screens and some optional correction. If elongation is set, will run the phase calculating and focal plane making methods multiple times for a few different heights of LGS, then sum these onto a wfsDetectorPlane.

Parameters:
  • scrns (list) – A list or dict containing the phase screens
  • correction (ndarray, optional) – The correction term to take from the phase screens before the WFS is run.
  • read (bool, optional) – Should the WFS be read out? if False, then WFS image is calculated but slopes not calculated. defaults to True.
  • iMatFrame (bool, optional) – If True, will assume an interaction matrix is being measured. Turns off some AO loop features before running
Returns:

WFS Measurements

Return type:

ndarray

initLGS()[source]

Initialises the LGS objects for the WFS

Creates and initialises the LGS objects if the WFS GS is a LGS. This included calculating the phases additions which are required if the LGS is elongated based on the depth of the elongation and the launch position. Note that if the GS is at infinity, elongation is not possible and a warning is logged.

initLos()[source]

Initialises the LineOfSight object, which gets the phase or EField in a given direction through turbulence.

makeElongationFrame(correction=None)[source]

Find the focal plane resulting from an elongated guide star, such as LGS.

Runs the phase stacking and propagation routines multiple times with different GS heights, positions and/or aberrations to simulation the effect of a number of points in an elongation guide star.

setMask(mask)[source]

Sets the pupil mask as seen by the WFS.

This method can be called during a simulation

class soapy.wfs.shackhartmann.ShackHartmann(soapy_config, n_wfs=0, mask=None)[source]

Class to simulate a Shack-Hartmann WFS

addPhotonNoise()[source]

Add photon noise to wfsDetectorPlane using numpy.random.poisson

addReadNoise()[source]

Adds read noise to wfsDetectorPlane using ``numpy.random.normal. This generates a normal (guassian) distribution of random numbers to add to the detector. Any CCD bias is assumed to have been removed, so the distribution is centred around 0. The width of the distribution is determined by the value eReadNoise set in the WFS configuration.

allocDataArrays()[source]

Allocate the data arrays the WFS will require

Determines and allocates the various arrays the WFS will require to avoid having to re-alloc memory during the running of the WFS and keep it fast.

A method to deal with convolving the LGS PSF with the subap focal plane.

calcFocalPlane(intensity=1)[source]

Calculates the wfs focal plane, given the phase across the WFS

Parameters:intensity (float) – The relative intensity of this frame, is used when multiple WFS frames taken for extended sources.
calcInitParams()[source]

Calculate some parameters to be used during initialisation

calcTiltCorrect()[source]

Calculates the required tilt to add to avoid the PSF being centred on only 1 pixel

calculateSlopes()[source]

Calculates WFS slopes from wfsFocalPlane

Returns:array of all WFS measurements
Return type:ndarray
findActiveSubaps()[source]

Finds the subapertures which are not empty space determined if mean of subap coords of the mask is above threshold.

getStatic()[source]

Computes the static measurements, i.e., slopes with flat wavefront

initFFTs()[source]

Initialise the FFT Objects required for running the WFS

Initialised various FFT objects which are used through the WFS, these include FFTs to calculate focal planes, and to convolve LGS PSFs with the focal planes

initLos()[source]

Initialises the LineOfSight object, which gets the phase or EField in a given direction through turbulence.

makeDetectorPlane()[source]

Scales and bins intensity data onto the detector with a given number of pixels.

If required, will first convolve final PSF with LGS PSF, then bin PSF down to detector size. Finally puts back into wfsFocalPlane array in correct order.

zeroData(detector=True, FP=True)[source]

Sets data structures in WFS to zero.

Parameters:
  • detector (bool, optional) – Zero the detector? default:True
  • FP (bool, optional) – Zero intermediate focal plane arrays? default: True