slmsuite.hardware.cameraslms.FourierSLM#

class FourierSLM(*args, **kwargs)[source]#

Bases: CameraSLM

Class for an SLM and camera separated by a Fourier transform. This class includes methods for system calibration.

calibrations#
“fourier”dict

The affine transformation that maps between the k-space of the SLM (kxy) and the pixel-space of the camera (ij).

See fourier_calibrate().

This data is critical for much of slmsuite’s functionality.

“wavefront”dict

Raw data for correcting aberrations in the optical system (phase) and measuring the optical amplitude distribution incident on the SLM (amp).

See wavefront_calibrate_zernike() and wavefront_calibrate_superpixel() Usable data for the superpixel implementation is produced by running wavefront_calibration_superpixel_process().

This data is critical for crisp holography.

“pixel”dict

Raw data for measuring the crosstalk and \(V_\pi\) of sections of the SLM via measurements on the diffractive orders of binary gratings.

See pixel_calibrate(). Usable data is produced by running pixel_calibration_process().

This data is currently unused; exploring computationally-efficient ways to apply the crosstalk without oversampling.

“settle”dict

Raw data for determining the temporal system response of the SLM.

See settle_calibrate(). Usable data is produced by running settle_calibration_process().

This data informs the user’s choice of settle_time_s, the time to wait to acquire data after a pattern is displayed. This is, of course, a tradeoff between measurement speed and measurement precision.

Type:

dict

Methods

fourier_calibrate

Project and fit a SLM computational Fourier space "knm" grid onto camera pixel space "ij" for affine fitting.

fourier_calibrate_analytic

Sets the Fourier calibration to a user-selected affine transformation.

fourier_calibration_build

Builds an affine transform defining the SLM to camera transformation as detailed in kxyslm_to_ijcam().

fourier_grid_project

Projects a Fourier space grid "knm" onto pixel space "ij".

get_effective_focal_length

Uses the Fourier calibration to estimate the scalar effective focal length of the optical train separating the Fourier-domain SLM from the camera.

get_farfield_spot_size

Calculates the size of a spot produced by blazed patch of size slm_size on the SLM.

ijcam_to_kxyslm

Converts camera pixel space ("ij") to SLM Fourier space ("kxy").

kxyslm_to_ijcam

Converts SLM Fourier space ("kxy") to camera pixel space ("ij").

load_calibration

from a file.

name_calibration

Creates "{self.name}-{calibration_type}-calibration".

pickle

Returns a dictionary containing selected attributes of this class.

pixel_calibrate

Measure the pixel crosstalk and phase response of the SLM.

pixel_calibration_process

Currently, this method only displays debug plots of the measurements.

pixel_kernel

Blurring kernel

plot

Plots the provided phase and image for the child hardware on a pair of subplot axes.

read_calibration

Backwards-compatibility alias for load_calibration().

save

Saves the dictionary returned from pickle() to a file like "path/name_id.h5".

save_calibration

to a file like "path/name_id.h5".

settle_calibrate

Approximates the \(1/e\) settle time of the SLM.

settle_calibration_process

Fits an exponential to the measured data to approximate the \(1/e\) settle time of the SLM.

simulate

Clones the hardware-based experiment into a "digital twin" for simulation.

wavefront_calibrate

Backwards-compatible method to switch between the superpixel wavefront_calibrate_superpixel() and Zernike wavefront_calibrate_zernike() implementations of wavefront calibration.

wavefront_calibrate_superpixel

Perform wavefront calibration by iteratively interfering superpixel patches on the SLM.

wavefront_calibrate_zernike

Perform wavefront calibration by iteratively scanning and subtracting Zernike coefficients.

wavefront_calibration_points

Generates a grid of points to perform wavefront calibration at.

wavefront_calibration_superpixel_process

Processes calibrations ["wavefront"] into the desired phase correction and amplitude measurement.

wavefront_calibration_superpixel_window

Returns the window size for the interference regions.

write_calibration

Backwards-compatibility alias for save_calibration().

__init__(*args, **kwargs)[source]#

See CameraSLM.__init__().

simulate()[source]#

Clones the hardware-based experiment into a “digital twin” for simulation.

Note

Since simulation mode needs the Fourier relationship between the SLM and camera, the FourierSLM should be Fourier-calibrated prior to cloning for simulation.

Returns:

A FourierSLM object with simulated hardware.

Return type:

FourierSLM

name_calibration(calibration_type)[source]#

Creates "{self.name}-{calibration_type}-calibration".

Parameters:

calibration_type (str) – The type of calibration to save. See calibrations for supported options.

Returns:

name – The generated name.

Return type:

str

write_calibration(calibration_type, path, name)[source]#

Backwards-compatibility alias for save_calibration().

save_calibration(calibration_type, path='.', name=None)[source]#

to a file like "path/name_id.h5".

Parameters:
  • calibration_type (str) – The type of calibration to save. See calibrations for supported options. Works for any key of calibrations.

  • path (str) – Path to directory to save in. Default is current directory.

  • name (str OR None) – Name of the save file. If None, will use name_calibration().

Returns:

The file path that the calibration was saved to.

Return type:

str

read_calibration(calibration_type, file_path=None)[source]#

Backwards-compatibility alias for load_calibration().

load_calibration(calibration_type, file_path=None)[source]#

from a file.

Parameters:
  • calibration_type (str) – The type of calibration to save. See calibrations for supported options.

  • file_path (str OR None) – Full path to the calibration file. If None, will search the current directory for a file with a name like the one returned by name_calibration().

Returns:

The file path that the calibration was loaded from.

Return type:

str

Raises:

FileNotFoundError – If a file is not found.

settle_calibrate(vector=(0.005, 0.005), size=None, times=None, settle_time_s=1)[source]#

Approximates the \(1/e\) settle time of the SLM. This is done by successively removing and applying a blaze to the SLM, measuring the intensity at the first order spot versus time delay.

(This feature is experimental.)

Parameters:
  • vector (array_like) – Point to measure settle time at via a simple blaze in the "kxy" basis.

  • size (int) – Size in pixels of the integration region in the "ij" basis. If None, sets to sixteen times the approximate size of a diffraction-limited spot.

  • times (array_like OR None OR int) – List of times to sweep over in search of the \(1/e\) settle time. If None, defaults to 21 points over one second. If an integer, defaults to that given number of points over one second.

  • settle_time_s (float OR None) – Time between measurements to allow the SLM to re-settle. If None, uses the current default in the SLM.

settle_calibration_process(plot=True)[source]#

Fits an exponential to the measured data to approximate the \(1/e\) settle time of the SLM.

Parameters:

plot (bool) – Whether to show a debug plot with the exponential fit.

Returns:

The settle time and communication time measured.

Return type:

dict

pixel_calibrate(levels=2, periods=2, orders=3, window=None, field_period=10)[source]#

Measure the pixel crosstalk and phase response of the SLM.

(This feature is experimental.)

Physical SLMs do not produce perfectly sharp and discrete blocks of a desired phase at each pixel. Rather, the realized phase might deviate from the desired phase (error) and be blurred between pixels (crosstalk).

We adopt a literature approach to calibrating both phenomena by measuring the system response of binary gratings. In the future, we intend to fit the measured data to an upgraded asymmetric model of phase crosstalk, and then apply the model to beam propagation during holographic optimization. A better understanding of the system error can lead to holograms that take this error into account.

Note that this algorithm does not operate at the level of individual pixels, but rather on aggregate statistics over a region of pixels. Right now, this calibration is done for one region (which defaults to the full SLM). In the future, we might want to calibrate many regions across the SLM to measure spatially varying phase response

Note

A Fourier calibration must be loaded.

Caution

Data must be acquired without wavefront calibration applied. If the uncalibrated SLM produces too defocussed of a spot, then this measurement may not be ideal. On the flip side, a too-focussed spot might increase error by integration over fewer camera pixels.

Parameters:
  • levels (int OR array_like of int) – Which bitlevels to test, out of the \(2^B\) levels available for a \(B\)-bit SLM. Note that runtime scales with \(\mathcal{O}(B^2)\). If an integer is passed, the integer is rounded to the next largest power of two, and this number of bitlevels are sampled.

  • periods (int OR array_like of int) – List of periods (in pixels) of the binary gratings that we will apply. Must be even integers. If a single int is provided, then a list containing the given number of periods is chosen, based upon the field of view of the camera.

  • orders (int OR array_like of int) – Orders (…, -1st, 0th, 1st, …) of the binary gratings to measure data at. If scalar is provided, measures orders between -nth and nth order, inclusive.

  • window – If not None, the pixel calibration is only done over the region of the SLM defined by window. Passed to window_slice(). See window_slice() for various options.

  • field_period (int) – If window is not None, then the field is deflected away in an orthogonal direction with a grating of the given period.

pixel_calibration_process()[source]#

Currently, this method only displays debug plots of the measurements. In the future, the measurements will be fit in a way that can be applied to propagation.

static pixel_kernel(x, a1_pix=0.1, a2_pix=0.1, n1=1, n2=1)[source]#

Blurring kernel

\[\begin{split}K(x) = \left\{ \begin{array}{ll} \exp\left(-\left|\frac{x}{\alpha_1}\right|^{n_1}\right), & x < 0, \\ \exp\left(-\left|\frac{x}{\alpha_2}\right|^{n_2}\right), & x \ge 0. \end{array} \right.\end{split}\]
fourier_calibrate(array_shape=10, array_pitch=10, array_center=None, plot=False, autofocus=False, autoexposure=False, **kwargs)[source]#

Project and fit a SLM computational Fourier space "knm" grid onto camera pixel space "ij" for affine fitting. An array produced by make_rectangular_array() is projected for analysis by blob_array_detect(). These arguments are in "knm" space because:

  • The "ij" space has not yet been calibrated.

  • The "kxy" space can lead to non-integer array_pitch in "knm"-space. This is not ideal (see Tip).

Tip

For best results, array_pitch should be integer data. Otherwise non-uniform rounding to the SLM’s computational \(k\)-space ("knm"-space) can result in non-uniform pitch and a bad fit. The user is warned if non-integer data is given.

Parameters:
  • array_shape – Passed to make_rectangular_array() in the "knm" basis.

  • array_pitch – Passed to make_rectangular_array() in the "knm" basis.

  • array_center – Passed to make_rectangular_array() in the "knm" basis. array_center is not passed directly, and is processed as being relative to the center of "knm" space, the position of the 0th order.

  • plot (bool OR int) –

    Enables debug plots:

    • 0 is no plots,

    • 1 is only the final fit plot, unless there is an error,

    • 2 is all plots.

  • autofocus (bool OR dict) – Whether or not to autofocus the camera. If a dictionary is passed, autofocus is performed, and the dictionary is passed to autofocus().

  • autoexposure (bool OR dict) – Whether or not to automatically set the camera exposure. If a dictionary is passed, autoexposure is performed, and the dictionary is passed to autoexposure().

  • **kwargs (dict) – Passed to fourier_grid_project(), which passes them to optimize().

Returns:

calibrations["fourier"]

Return type:

dict

fourier_grid_project(array_shape=10, array_pitch=10, array_center=None, **kwargs)[source]#

Projects a Fourier space grid "knm" onto pixel space "ij". The chosen computational \(k\)-space "knm" uses a computational shape generated by get_padded_shape() corresponding to the smallest square shape with power-of-two sidelength that is larger than the SLM’s shape.

Parameters:
Returns:

Optimized hologram.

Return type:

SpotHologram

fourier_calibrate_analytic(M, b)[source]#

Sets the Fourier calibration to a user-selected affine transformation.

See fourier_calibration_build() to generate this transformation from a known or measured focal length.

Parameters:
  • numpy.ndarray – Affine matrix \(M\). Shape (2, 2).

  • numpy.ndarray – Affine vector \(b\). Shape (1, 2).

Returns:

calibrations["fourier"]

Return type:

dict

fourier_calibration_build(f_eff, units='norm', theta=0, shear_angle=0, offset=None)[source]#

Builds an affine transform defining the SLM to camera transformation as detailed in kxyslm_to_ijcam().

Parameters:
  • f_eff (float OR (float, float)) – Effective focal length of the optical train separating the Fourier-domain SLM from the camera. If a float is provided, f_eff is isotropic; otherwise, f_eff is defined along the SLM’s \(x\) and \(y\) axes.

  • units (str {"norm", "ij", "m", "cm", "mm", "um", "nm"}) –

    Units for the focal length f_eff.

    • "norm"

      Normalized focal length in wavelengths according to the SLM’s wav_um. This is the default unit.

    • "ij"

      Focal length in units of camera pixels.

    • "m", "cm", "mm", "um", "nm"

      Focal length in metric units.

  • theta (float) – Rotation angle (in radians, ccw) of the camera relative to the SLM orientation. Defaults to zero (i.e., aligned with the SLM).

  • shear_angle (float OR (float, float)) – Shearing angles (in radians) along the SLM’s \(x\) and \(y\) axes. If a float is provided, shear is applied isotropically. Defaults to zero (i.e., no shear).

  • offset ((float, float) OR None) – Lateral displacement (in pixels units) of the SLM’s optical axis from the camera’s origin. If None, defaults to be centered on the center of the camera.

Returns:

  • numpy.ndarray – Affine matrix \(M\). Shape (2, 2).

  • numpy.ndarray – Affine vector \(b\). Shape (1, 2).

kxyslm_to_ijcam(kxy)[source]#

Converts SLM Fourier space ("kxy") to camera pixel space ("ij"). For blaze vectors \(\vec{x}\) and camera pixel indices \(\vec{y}\), computes:

\[\vec{y} = M \cdot (\vec{x} - \vec{a}) + \vec{b}\]

where \(M\), \(\vec{b}\), and \(\vec{a}\) are stored in

If the vectors are three-dimensional, the third depth dimension is treated according to:

\[y_z = \frac{f_\text{eff}^2}{\pi}x_z\]

where \(y_z\) is the normalized depth of the spot relative to the focal plane and \(x_z\) is equivalent to focal power, equivalent to the the quadratic term of a simple thin lens(). The constant of proportionality makes use of the normalized effective focal length \(f_\text{eff}\) of the imaging system between the SLM and camera. This information is encoded in the Fourier calibration, and revealed by get_effective_focal_length().

Parameters:

kxy (array_like) – Vector or array of vectors to convert. Can be 2D or 3D. Cleaned with format_vectors().

Returns:

ij – Vector or array of vectors in camera spatial coordinates. Can be 2D or 3D.

Return type:

numpy.ndarray

Raises:

RuntimeError – If the fourier plane calibration does not exist.

ijcam_to_kxyslm(ij)[source]#

Converts camera pixel space ("ij") to SLM Fourier space ("kxy"). For camera pixel indices \(\vec{y}\) and blaze vectors \(\vec{x}\), computes:

\[\vec{x} = M^{-1} \cdot (\vec{y} - \vec{b}) + \vec{a}\]

where \(M\), \(\vec{b}\), and \(\vec{a}\) are stored in calibrations["fourier"].

Important

If the vectors are three-dimensional, the third depth dimension is treated according to:

\[x_z = \frac{1}{f} = \frac{1}{f_\text{eff}^2}\frac{\Delta_{xy} y_z}{\lambda}\]

where \(x_z\), equivalent to normalized focal power, is the focal term needed to focus a spot at \(y_z\) pixel depth. Here, \(\frac{\Delta_{xy} y_z}{\lambda}\) is the same depth in normalized units. Importantly, this is depth relative to the plane of the camera, which might differ from the relative depth in an experimental plane. Focal power is equivalent to the the quadratic term of a simple thin lens(). The constant of proportionality makes use of the normalized effective focal length \(f_\text{eff}\) of the imaging system between the SLM and camera. This information is encoded in the Fourier calibration, and revealed by get_effective_focal_length().

Parameters:

ij (array_like) – Vector or array of vectors to convert. Can be 2D or 3D. Cleaned with format_2vectors().

Returns:

kxy – Vector or array of vectors in slm angular coordinates. Can be 2D or 3D.

Return type:

numpy.ndarray

Raises:

RuntimeError – If the fourier plane calibration does not exist.

get_farfield_spot_size(slm_size=None, basis='kxy')[source]#

Calculates the size of a spot produced by blazed patch of size slm_size on the SLM. If this patch is the size of the SLM, then we will find in the farfield (camera) domain, the size of a diffraction-limited spot for a fully-illuminated surface. As the slm_size of the patch on the SLM decreases, the diffraction limited spot size in the farfield domain will of course increase. This calculation is accomplished using the calibration produced by fourier_calibrate() and stored in calibrations["fourier"].

Parameters:
  • slm_size ((float, float) OR int OR float OR None) – Size of patch on the SLM in normalized units. A scalar is interpreted as the width and height of a square. If None, defaults to the normalized SLM size.

  • basis ({"kxy", "ij"}) – Basis of the returned size; "kxy" for SLM \(k\)-space, "ij" for camera size.

Returns:

Size in x and y of the spot in the desired basis.

Return type:

(float, float)

Raises:

ValueError – If the basis argument was malformed.

get_effective_focal_length(units='norm')[source]#

Uses the Fourier calibration to estimate the scalar effective focal length of the optical train separating the Fourier-domain SLM from the camera. This currently assumes an isotropic imaging train without cylindrical optics.

Tip

This effective focal length between the SLM and camera is potentially different from the effective focal length between the SLM and experiment.

Parameters:

units (str {"ij", "norm", "m", "cm", "mm", "um", "nm"}) –

Units for the focal length.

  • "ij"

    Focal length in units of camera pixels.

  • "norm"

    Normalized focal length in wavelengths.

  • "m", "cm", "mm", "um", "nm"

    Focal length in metric units.

Returns:

f_eff – Effective focal length.

Return type:

float

wavefront_calibrate(*args, method=None, **kwargs)[source]#

Backwards-compatible method to switch between the superpixel wavefront_calibrate_superpixel() and Zernike wavefront_calibrate_zernike() implementations of wavefront calibration.

wavefront_calibrate_zernike(calibration_points=None, zernike_indices=9, perturbation=1, callback=None, metric=None, optimize_focus=True, plot=0)[source]#

Perform wavefront calibration by iteratively scanning and subtracting Zernike coefficients.

Parameters:
  • calibration_points ((float, float) OR numpy.ndarray OR float OR None) –

    Position(s) in the camera domain where interference occurs. A passed array should be a standard (D, N) matrix, where D is the dimension of the Zernike space and N is the number of points. If int, fills the camera field of view with roughly this number of calibration points. If None, defaults to 100 points, unless a calibration is already saved in calibrations under the "wavefront_zernike" key, in which case the "corrected_spots" from the calibration are used as the baseline. This allows the user to iterate on previous calibrations. Note that zernike_indices is also overwritten in this case.

    Important

    These coordinates must be in the "zernike" basis. Use convert_vector() to convert between 2 or 3 dimensional coordinates to their Zernike counterparts.

  • zernike_indices (int OR list of int OR None) –

    Which Zernike polynomials to calibrate against, defined by ANSI indices. Of shape (D,).

    Tip

    Use zernike_convert_index() to convert to ANSI from various other common indexing conventions.

    Important

    If None is passed, the assumed Zernike basis depends on the dimensionality of the provided spots:

    • If D == 2, then the basis is assumed to be [2,1] corresponding to the \(x = Z_2 = Z_1^1\) and \(y = Z_1 = Z_1^{-1}\) tilt terms.

    • If D == 3, then the basis is assumed to be [2,1,4] corresponding to the previous, with the addition of the \(Z_4 = Z_2^0\) focus term.

    • If D > 3, then the basis is assumed to be [2,1,4,3,5,6...,D]. The piston term (Zernike index 0) is ignored as this constant phase is not relevant.

  • perturbation (list of float OR float OR None) – Perturbation in radians to iteratively multiply with each of the \(\pm 1\)-normalized Zernike terms. If float, tests 11 points in a range of plus to minus this value in radians. Defaults to a range of \(\pm 1\) radians. If 0 or None, the starting spots are projected and the function returns before optimizing.

  • callback (None OR function) – Measure the system to determine the level of aberration. Expected to return a list of floats of length N corresponding to the chosen metric evaluated on all the spots. The optimizer will minimize the figure of merit. This data is fit using a parabola, and the x-offset of the parabola is interpreted as the minimum aberration.

  • metric (None OR function) – If callback is None, then the camera is used to measure the system. This parameter allows the user to impart a custom figure of merit upon the measured camera data. metric is required to accept a stack of N images consisting of the regions about each of the N target spots. It is expected to return a list of length N corresponding to the chosen metric evaluated on all the images. If None, _wavefront_calibrate_zernike_default_metric() is used, which is just a wrapper for image_areas(), a measurement of spot size. The optimizer will minimize the figure of merit.

  • optimize_focus (bool) – If False, does not optimize the focus term (ansi index 4). Useful in cases where the callback method is insensitive to z()-translation (e.g. Stark effect of an atom) or in cases where the z() axis should be unchanged.

  • plot (int or bool) –

    Whether to provide visual feedback, options are:

    • -1 : No plots or tqdm prints.

    • 0, False : No plots, but tqdm prints.

    • 1, True : Plots on fits and essentials.

    • 2 : Plots on everything.

Returns:

The contents of calibrations["wavefront"].

Return type:

dict

Raises:
  • RuntimeError – If the Fourier plane calibration does not exist.

  • ValueError – If various points are out of range.

wavefront_calibrate_superpixel(calibration_points=None, superpixel_size=50, reference_superpixels=None, exclude_superpixels=(0, 0), test_index=None, field_point=(0, 0), field_point_units='kxy', phase_steps=1, fresh_calibration=True, measure_background=False, corrected_amplitude=False, plot=0)[source]#

Perform wavefront calibration by iteratively interfering superpixel patches on the SLM. This procedure measures the wavefront phase and amplitude.

Interference occurs at a given calibration_points in the camera’s imaging plane. It is at each point where the computed correction is ideal; the further away from each point, the less ideal the correction is. Correction at many points over the plane permits a better understanding of the aberration and greater possibility of compensation.

Sets calibrations["wavefront"]. Run wavefront_calibration_process() afterwards to produce the usable calibration which can be written to the SLM.

Note

A Fourier calibration must be loaded.

Tip

If only amplitude calibration is desired, use phase_steps=None to omit the more time-consuming phase calibration.

Tip

Use phase_steps=1 for faster calibration. This fits the phase fringes of an image rather than scanning the fringes over a single camera pixel over many phase_steps. This is usually optimal except in cases with excessive noise.

Parameters:
  • calibration_points ((float, float) OR numpy.ndarray OR None) – Position(s) in the camera domain where interference occurs. For multiple positions, this must be of shape (2, N). This is naturally in the "ij" basis. If None, densely fills the camera field of view with calibration points.

  • superpixel_size (int) – The width and height in pixels of each SLM superpixel. If this is not a devisor of both dimensions in the SLM’s shape, then superpixels at the edge of the SLM may be cropped and give undefined results. Currently, superpixels are forced to be square, and this value must be a scalar.

  • reference_superpixels ((int,int) OR numpy.ndarray of int OR None) – The coordinate(s) of the superpixel(s) to reference from. For multiple positions, this must be of shape (2, N). Defaults to the center of the SLM if None. If multiple calibration points are requested when None, then the references are clustered at the center.

  • exclude_superpixels ((int, int) OR numpy.ndarray OR None) – If in (nx, ny) form, optionally exclude superpixels from the margin, That is, the nx superpixels are omitted from the left and right sides of the SLM, with the same for ny. As power is typically concentrated in the center of the SLM, this function is useful for excluding points that are known to be blocked (e.g. with an iris or other pupil), or for quickly testing calibration at the most relevant points. Otherwise, if exclude_superpixels is an image with the same dimension as the superpixeled SLM, this image is interpreted as a denylist. Defaults to None, where no superpixels are excluded.

  • test_index (int OR None) –

    If int, then tests the scheduled calibration corresponding to this index. Defaults to None, which runs the full wavefront calibration instead of testing at only one index.

    Note

    Scheduling is relative to the reference superpixel(s), and a change to the reference may also shift the positions of the test superpixels for the given index.

  • field_point ((float, float)) – Position in the camera domain where the field (pixels not included in superpixels) is blazed toward in order to reduce light in the camera’s field. The suggested approach is to set this outside the field of view of the camera and make sure that other diffraction orders are far from the calibration_points. Defaults to no blaze ((0,0) in "kxy" units).

  • field_point_units (str) –

    A unit compatible with convert_vector(). Defaults to "kxy".

    Tip

    Setting one coordinate of field_point to zero is suggested to minimize higher order diffraction.

  • phase_steps (int OR None) –

    The number of interference phases to measure. If phase_steps is 1 (the default), does a one-shot fit on the interference pattern to improve speed.

    Tip

    If phase_steps is ``None`, phase is not measured and only amplitude is measured.

  • fresh_calibration (bool) – If True, the calibration is performed without an existing calibration (any old global calibration is wiped from the SLM and CameraSLM). If False, the calibration is performed on top of any existing calibration. This is useful to determine the quality of a previous calibration, as a new calibration should yield zero phase correction needed if the previous was perfect. The old calibration will be stored in the calibrations under "previous_phase_correction", so keep in mind that this (uncompressed) image will take up significantly more space.

  • measure_background (bool) – Whether to measure the background at each point.

  • corrected_amplitude (bool) – If False, the power in the uncorrected target beam is used as the source of amplitude measurement. If True, adds another step to measure the power of the corrected target beam.

  • plot (int or bool) –

    Whether to provide visual feedback, options are:

    • -1 : No plots or tqdm prints.

    • 0, False : No plots, but tqdm prints.

    • 1, True : Plots on fits and essentials.

    • 2 : Plots on everything.

    • 3 : test_index not None only: returns image frames to make a movie from the phase measurement (not for general use).

Returns:

The contents of calibrations["wavefront"].

Return type:

dict

Raises:
  • RuntimeError – If the Fourier plane calibration does not exist.

  • ValueError – If various points are out of range.

wavefront_calibration_points(pitch, field_exclusion=None, field_point=(0, 0), field_point_units='kxy', avoid_points=None, avoid_mirrors=True, plot=False)[source]#

Generates a grid of points to perform wavefront calibration at.

Parameters:
  • pitch (float OR (float, float)) – The grid of points must have pitch greater than this value.

  • field_exclusion (float OR None) – Remove all points within field_exclusion of a field_point. Set to zero if no removal is desired. If None, defaults to pitch.

  • field_point ((float, float)) – Position in the camera domain where the field (pixels not included in superpixels) is blazed toward in order to reduce light in the camera’s field. The suggested approach is to set this outside the field of view of the camera and make sure that other diffraction orders are far from the calibration_points. Defaults to no blaze ((0,0) in "kxy" units).

  • field_point_units (str) –

    A unit compatible with convert_vector(). Defaults to "kxy".

    Tip

    Setting one coordinate of field_point to zero is suggested to minimize higher order diffraction.

  • avoid_points (numpy.ndarray) – Additional points to avoid in the same manner as avoiding the field_point and diffractive orders (with the same radius field_exclusion). This can, for instance, omit the points outside the camera’s field of view, points around known stray reflections, or unusual topology.

  • avoid_mirrors (bool) – When a 1st order calibration beam is sourced from a weak superpixel in the SLM domain, the -1st order of a different calibration beam can act as a strong noise source if it is sourced from a strong central superpixel. If True, this flag aligns the -1st orders to be inbetween the 1st orders of the grid of calibration points.

Returns:

List of points of shape (2, N) to calibrate at in the "ij" basis.

Return type:

numpy.ndarray

Raises:

AssertionError – If the fourier plane calibration does not exist.

wavefront_calibration_superpixel_window(superpixel_size)[source]#

Returns the window size for the interference regions. This is inversely proportional to the size of the superpixel because the superpixel and interference zone are separated by a Fourier transform. The computation works by estimating the spot size of the interference beams and then enlarging by a stored multiplier _wavefront_calibration_window_multiplier which defaults to 4.

Parameters:

superpixel_size (int) – The size of the superpixel on the SLM.

wavefront_calibration_superpixel_process(index=0, smooth=True, r2_threshold=0.9, apply=True, plot=False)[source]#

Processes calibrations ["wavefront"] into the desired phase correction and amplitude measurement. Applies these parameters to the respective variables in the SLM if apply is True.

Parameters:
  • index (int) – The calibration point index to process, in the case of a multi-point calibration. In the future, this should include the option to request an “ij” position, then the return will automatically interpolate between the Zernike results of the local calibration points.

  • smooth (bool) – Whether to blur the correction data to avoid aliasing.

  • r2_threshold (float) – Threshold for a “good fit”. Proxy for whether a datapoint should be used or ignored in the final data, depending upon the rsquared value of the fit. Should be within [0, 1].

  • apply (bool) – Whether to apply the processed calibration to the associated SLM. Otherwise, this function only returns and maybe plots these results. Defaults to True.

  • plot (bool) – Whether to enable debug plots.

Returns:

The updated source dictionary containing the processed source amplitude and phase.

Return type:

dict

pickle(attributes=True, metadata=True)[source]#

Returns a dictionary containing selected attributes of this class.

Parameters:
  • attributes (bool OR list of str) – If False, pickles only baseline attributes, usually single floats. If True, also pickles ‘heavy’ attributes such as large images and calibrations. If list of str, pickles the keys in the given list. By default, the chosen attributes should be things that can be written to .h5 files: scalars and lists of scalars.

  • metadata (bool) – If True, package the dictionary as the "__meta__" value of a superdictionary which also contains: "__version__", the current slmsuite version, "__time__", the time formatted as a date string, and "__timestamp__", the time formatting as a floating point timestamp. This information is used as standard metadata for calibrations and saving.

plot(phase=None, image=None, slm_limits=None, cam_limits=None, title='', axs=None, cbar=True, **kwargs)[source]#

Plots the provided phase and image for the child hardware on a pair of subplot axes.

Parameters:
  • phase (ndarray OR None) –

    Phase to be plotted. If None, grabs the last written phase from the SLM.

    Important

    Writes this phase to the SLM if image is None.

  • image (ndarray OR None) – Image to be plotted. If None, grabs an image from the camera.

  • slm_limits (None OR float OR [[float, float], [float, float]]) – Scales the limits by a given factor or uses the passed limits directly.

  • cam_limits (None OR float OR [[float, float], [float, float]]) – Scales the limits by a given factor or uses the passed limits directly.

  • title (str) – Super title for the axes.

  • ax ((matplotlib.pyplot.axis, matplotlib.pyplot.axis) OR None) – Axes to plot upon.

  • cbar (bool) – Also plot a colorbar.

  • **kwargs – Passed to set_phase()

Returns:

Axes of the plotted phase and image.

Return type:

(matplotlib.pyplot.axis, matplotlib.pyplot.axis)

save(path='.', name=None, **kwargs)[source]#

Saves the dictionary returned from pickle() to a file like "path/name_id.h5".

Parameters:
  • path (str) – Path to directory to save in. Default is current directory.

  • name (str OR None) – Name of the save file. If None, will use name + '-pickle'.

  • **kwargs – Passed to pickle() to customize how and what data is saved.

Returns:

The file path that the pickled data was saved to.

Return type:

str