12.6. openwfs.utilities

class Transform(transform=None, source_origin=None, destination_origin=None)[source]

Bases: object

Represents a transformation from one 2-d coordinate system to another.

Transform objects are used to specify any combination of shift, (anisotropic) scaling, rotation and shear. The transform matrix, as well as the source and destination origins, can be specified with astropy units attached.

Note that a Transform object does not contain any information about the extent and pixel size of the source or destination image, it only specifies the coordinate transformation itself. When a Transform object is used to transform image data (see project() and place()), the pixel_size information should be specified separately.

apply(vector)[source]

Applies the transformation to a column vector.

If vector is a 2-D array, applies the transformation to each column of vector individually.

compose(other)[source]

Compose two transformations.

Parameters:

other (Transform) – the transformation to apply first

Returns:

Transform – the composition of the two transformations

cv2_matrix(source_shape, source_pixel_size, destination_shape, destination_pixel_size)[source]

Returns the transformation matrix in the format used by cv2.warpAffine.

destination_unit(src_unit)[source]

Computes the unit of the output of the transformation, given the unit of the input.

Raises:

ValueError – If src_unit does not match the unit of the source_origin (if specified) or if dst_unit does not match the unit of the destination_origin (if specified).

classmethod identity()[source]
inverse()[source]

Compute the inverse transformation, such that the composition of the transformation and its inverse is the identity.

opencl_matrix()[source]
to_matrix(source_pixel_size, destination_pixel_size)[source]
static zoom(scale)[source]

Returns a transform that just zooms in the image.

coordinate_range(shape, extent, offset=None)[source]

Returns coordinate vectors for the two coordinates (y and x).

Given a range from -extent/2 to +extent/2, uniformly divided into shape pixels, the returned coordinates correspond to the centers of these coordinates.

Parameters:
  • shape (ShapeType) – size of the full grid (y, x) in pixels

  • extent (ExtentType) – extent of the coordinate range

  • offset (Optional[CoordinateType]) – offset to be added to the coordinates (optional)

Returns:

Tuple[Quantity, Quantity] – coordinate vectors for the two coordinates (y and x)

disk(shape, radius=1.0, extent=(2.0, 2.0))[source]

Constructs an image of a centered (ellipsoid) disk.

(x / rx)^2 + (y / ry)^2 <= 1.0

Parameters:
  • shape (Union[int, Sequence[int]]) – see module documentation

  • radius (ScalarType) – radius of the disk, should have the same unit as extent.

  • extent (Union[float, Sequence[float], ndarray, Quantity]) – see module documentation

gaussian(shape, waist, truncation_radius=None, extent=(2.0, 2.0))[source]

Constructs an image of a centered Gaussian

waist, extent and the optional truncation_radius should all have the same unit.

Parameters:
  • shape (Union[int, Sequence[int]]) – see module documentation

  • waist (ScalarType) – location of the beam waist (1/e value) relative to half of the size of the pattern (i.e. relative to the radius of the square)

  • truncation_radius (ScalarType) – when not None, specifies the radius of a disk that is used to truncate the Gaussian. All values outside the disk are set to 0.

  • extent (Union[float, Sequence[float], ndarray, Quantity]) – see module documentation

get_extent(data)[source]

Extracts the extent from the data array. The extent is always equal to shape * pixel_size.

get_pixel_size(data)[source]

Extracts the pixel size metadata from the data array.

Parameters:

data (np.ndarray) – The input data array or Quantity.

Returns:

OptionalQuantity] – The pixel size metadata, or None if no pixel size metadata is present.

Usage: >>> import astropy.units as u >>> import numpy as np >>> data = set_pixel_size(((1, 2), (3, 4)), 5 * u.um) >>> pixel_size = get_pixel_size(data)

TODO: return 1 if no pixel size is present

place(out_shape, out_pixel_size, source, offset=None, out=None)[source]

Takes a source array and places it in an otherwise empty array of specified shape and pixel size.

The source array must have a pixel_size property (see set_pixel_size). It is scaled (using area interpolation) so that the pixel size matches that of the output. Then, the source array is placed into the output array at the position given by offset, where offset=None or offset=(0.0, 0.0) * pixel_size corresponds to centering the source image with respect to the output array. Parts of the source array that extend beyond the output are cropped, and parts of the array that are not covered by the source array are zero padded.

Note: this function currently works for 2-D inputs only

Args:

project(source, *, source_extent=None, transform=None, out=None, out_extent=None, out_shape=None)[source]

Projects the input image onto an array with specified shape and resolution.

The input image is scaled so that the pixel sizes match those of the output, and cropped/zero-padded so that the data shape matches that of the output. Optionally, an additional Transform can be specified, e.g., to scale or translate the source image.

Parameters:
  • source (ndarray) – input image.

  • source_extent (Union[float, Sequence[float], ndarray, Quantity, None]) – extent of the source image in some physical unit. If not given (None), the extent metadata of the input image is used. see get_extent().

  • transform (Optional[Transform]) – optional transformed (rotate, translate, etc.) to appy to the source image before placing it in the output

  • out (Optional[ndarray]) – optional array where the output image is stored in.

  • out_extent (Union[float, Sequence[float], ndarray, Quantity, None]) – extent of the output image in some physical unit. If not given, the extent metadata of the out image is used.

  • out_shape (Optional[tuple[int, ...]]) – shape of the output image. This value is ignored if out is specified.

Returns:

np.ndarray – the projected image (out if specified, otherwise a new array)

set_extent(data, extent)[source]

Sets the extent metadata for the given data array.

Parameters:
  • data (ArrayLike) – The input data array.

  • extent (ArrayLike) – The extent to be set. When a single-element extent is given, it is broadcasted to all dimensions of the data array. Passing None sets the extent metadata to None.

Returns:

np.ndarray – The modified data array with the extent metadata.

Usage: >>> data = np.array([[1, 2], [3, 4]]) >>> extent = 0.1 * u.m >>> modified_data = set_extent(data, extent)

set_pixel_size(data, pixel_size)[source]

Sets the pixel size metadata for the given data array.

Parameters:
  • data (ArrayLike) – The input data array.

  • pixel_size (Optional[Quantity]) – The pixel size to be set. When a single-element pixel size is given, it is broadcasted to all dimensions of the data array. Passing None sets the pixel size metadata to None.

Returns:

np.ndarray – The modified data array with the pixel size metadata.

Usage: >>> data = np.array([[1, 2], [3, 4]]) >>> pixel_size = 0.1 * u.m >>> modified_data = set_pixel_size(data, pixel_size)

tilt(shape, g, extent=(2.0, 2.0), phase_offset=0.0)[source]

Constructs a linear gradient pattern φ=2 g·r

Parameters:
  • shape (Union[int, Sequence[int]]) – see module documentation

  • g (tuple of two floats) – gradient vector. This has the unit: 1 / extent.unit. For the default extent of (2.0, 2.0), a value of g=(1,0) corresponds to having a ramp from -2 to +2 over the height of the pattern When this pattern is used as a phase in a pupil-conjugate configuration, this corresponds to a displacement of -2/π times the Abbe diffraction limit (e.g. a positive x-gradient g causes the focal point to move in the _negative_ x-direction)

  • extent (Union[float, Sequence[float], ndarray, Quantity]) – see module documentation

  • phase_offset (float) – optional additional phase offset to be added to the pattern

unitless(data)[source]

Converts an object to a numpy array. Especially useful to remove the scaling from a unitless Quantity.

Parameters:
  • data (Union[_SupportsArray[dtype[Any]], _NestedSequence[_SupportsArray[dtype[Any]]], bool, int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float, complex, str, bytes]]]) – The input data.

  • Quantity (If data is a)

  • a (it is converted to)

  • is. (All other data types are just returned as)

Returns:

ArrayLike – unitless numpy array, or the input data if it is not a Quantity.

Raises:

UnitConversionError – If the data is a Quantity with a unit

Note

Do NOT use np.array(data) to convert a Quantity to a numpy array, because this will drop the unit prefix. For example, np.array(1 * u.s / u.ms) == 1. Whereas unitless(1 * u.s / u.ms) == 1000 gives the correct answer.

Usage: >>> data = np.array([1.0, 2.0, 3.0]) * u.m >>> unitless_data = unitless(data)