prysm.x.dm#

Deformable Mirrors.

class prysm.x.dm.DM(ifn, Nout, Nact=50, sep=10, shift=(0, 0), rot=(0, 0, 0), upsample=1, project_centering='fft')#

Bases: object

A DM whose actuators fill a rectangular region on a perfect grid, and have the same influence function.

Create a new DM model.

This model is based on convolution of a ‘poke lattice’ with the influence function. It has the following idiosyncracies:

  1. The poke lattice is always “FFT centered” on the array, i.e. centered on the sample which would contain the DC frequency bin after an FFT.

  2. The rotation is applied in the same sampling as ifn

  3. Shifts and resizing are applied using a Fourier method and not subject to quantization

Parameters:
  • ifn (numpy.ndarray) – influence function; assumes the same for all actuators and must be the same shape as (x,y). Assumed centered on N//2th sample of x, y. Assumed to be well-conditioned for use in convolution, i.e. compact compared to the array holding it

  • Nout (int or tuple of int, length 2) – number of samples in the output array; see notes for details

  • Nact (int or tuple of int, length 2) – (X, Y) actuator counts

  • sep (int or tuple of int, length 2) – (X, Y) actuator separation, samples of influence function

  • shift (tuple of float, length 2) – (X, Y) shift of the actuator grid to (x, y), units of x influence function sampling. E.g., influence function on 0.1 mm grid, shift=1 = 0.1 mm shift. Positive numbers describe (rightward, downward) shifts in image coordinates (origin lower left).

  • rot (tuple of int, length <= 3) – (Z, Y, X) rotations; see coordinates.make_rotation_matrix

  • upsample (float) – upsampling factor used in determining output resolution, if it is different to the resolution of ifn.

  • project_centering (str, {'fft', 'interpixel'}) – how to deal with centering when projecting the surface into the beam normal fft = the N/2 th sample, rounded to the right, defines the origin. interpixel = the N/2 th sample, without rounding, defines the origin

Notes

If ifn is 500x500 and upsample=0.5, then the nominal output array is 250x250. If this is supposed to line up with a pupil embedded in a 512x512 array, then the user would have to call pad2d after, which is slightly worse than one stop shop.

The Nout parameter allows the user to specify Nout=512, and the DM’s render method will internally do the zero-pad or crop necessary to achieve the desired array size.

copy()#

Make a (deep) copy of this DM.

render(wfe=True)#

Render the DM’s surface figure or wavefront error.

Parameters:

wfe (bool, optional) – if True, converts the “native” surface figure error into reflected wavefront error, by multiplying by 2 times the obliquity. obliquity is the cosine of the rotation vector.

Returns:

surface figure error or wfe, projected into the beam normal by self.rot

Return type:

numpy.ndarray

render_backprop(protograd, wfe=True)#

Gradient backpropagation for render().

Parameters:
  • protograd (numpy.ndarray) –

    “prototype gradient” the array holding the work-in-progress towards the gradient. For example, in a problem fitting actuator commands to a surface, you might have:

    render() returns a 512x512 array, for 48x48 actuators. y contains a 512x512 array of target surface heights

    The euclidean distance between the two as a cost function: cost = np.sum(abs(render() - y)**2)

    Then the first step in computing the gradient is diff = 2 * (render() - y)

    and you would call dm.render_backprop(diff)

  • wfe (bool, optional) – if True, the return is scaled as for a wavefront error instead of surface figure error

Returns:

analytic gradient, shape Nact x Nact

Return type:

numpy.ndarray

Notes

Not compatible with complex valued protograd