13.5. openwfs.simulation

class ADCProcessor(source, analog_max, digital_max=65535, amplifier_bias=0.0, shot_noise=False, gaussian_noise_std=0.0, multi_threaded=True, generator=None)[source]

Bases: Processor

Mimics an analog-digital converter.

At the moment, only positive input and output values are supported.

property analog_max: float | None

Maximum value that the ADC can handle as input

This value and all higher values are converted to digital_max. When set to 0.0, the input signal is scaled automatically so that the maximum corresponds to digital_max

property conversion_factor: float | None

Conversion factor between analog and digital values. If analog_max is set to None, each frame is auto-scaled, and this function returns None.

property digital_max: int

Maximum value that the ADC can output.

Default value is 0xFFFF (16 bits)

property gaussian_noise_std: float
property shot_noise: bool

when True, apply Poisson noise to the data instead of rounding

class Camera(source, shape=None, pos=None, exposure=<Quantity 1. ms>, **kwargs)[source]

Bases: ADCProcessor

Wraps any 2-D image source as a camera.

The camera adds shot noise,

To implement the camera interface, in addition to the Detector interface, we must implement left,right,top, and bottom. In addition, the data should be returned as uint16. Conversion to uint16 is implemented in the ADCProcessor base class.

property bottom: int

Vertical end position of the ROI.

Type:

bottom (int)

property data_shape

This default implementation returns the data shape of the first source.

property exposure: Annotated[Quantity, Unit('ms')]
property height: int

Height of the ROI.

property left: int

Horizontal start position of the ROI.

Type:

left (int)

property right: int

Horizontal end position of the ROI.

Type:

right (int)

property top: int

Vertical start position of the ROI.

Type:

top (int)

property width: int

Width of the ROI.

class LinearStage(step_size)[source]

Bases: Actuator

Mimics a linear translation stage

home()[source]
property position: Annotated[Quantity, Unit('um')]
property step_size: Annotated[Quantity, Unit('um')]
class Microscope(source, *, data_shape=None, numerical_aperture=1.0, wavelength, nonlinearity=1, magnification=1.0, xy_stage=None, z_stage=None, immersion_refractive_index=1.0, incident_field=None, incident_transform=None, aberrations=None, aberration_transform=None, multi_threaded=True)[source]

Bases: Processor

A simulated microscope with pupil-conjugate SLM.

The microscope simulates physical effects such as aberrations and noise, as well as devices typically found in a wavefront shaping microscope: a spatial light modulator, translation stages, and a camera. This simulation is designed to test algorithms for wavefront shaping and alignment.

The simulation takes the field at the SLM, applies the phase aberrations, and masks the field with a pupil function corresponding to the numerical aperture of the microscope objective. This field is then Fourier transformed to obtain the intensity point spread function, with which the source image is convolved.

Finally, the resulting image is mapped to the camera using a magnification factor, or affine transformation matrix. The propagation is normalized such that a pupil fully filled with a field strength of 1.0 will produce an image that has the same total intensity as the source image.

property abbe_limit: Quantity

λ/(2 NA).

This is the theoretical resolution limit of the microscope due to diffraction.

Returns:

Quantity – The Abbe diffraction limit in length units.

Type:

Returns the Abbe diffraction limit

property data_shape: tuple

Returns the shape of the image in the image plane.

Returns:

tuple – The dimensions of the output image (height, width).

property magnification: float

Magnification from object plane to image plane.

Note that, as in a real microscope, the magnification does not affect the effective resolution of the image. The resolution is determined by the Abbe diffraction limit λ/2NA.

Returns:

float – The current magnification factor.

property pixel_size: Quantity

Returns the pixel size in the image plane.

This value is always equal to source.pixel_size * magnification.

Returns:

Quantity – The physical size of each pixel in the image plane.

class NoiseSource(noise_type, *, data_shape, pixel_size, multi_threaded=True, generator=None, **kwargs)[source]

Bases: Detector

property data_shape: Tuple[int, ...]

The shape of the data array that read() will return.

For some detectors this property may be mutable, for example, for a camera it represents the height and width of the ROI, which can be changed.

class PhaseToField(slm_phases, field_amplitude=1.0, non_modulated_field_fraction=0.0)[source]

Bases: Processor

Takes a phase as input and returns a field

Computes amplitude * (exp(1j * phase) + non_modulated_field_fraction)

class SLM(shape, latency=0.0 * u.ms, duration=0.0 * u.ms, update_latency=0.0 * u.ms, update_duration=0.0 * u.ms, refresh_rate=0 * u.Hz, field_amplitude=1.0, non_modulated_field_fraction=0.0, phase_response=None)[source]

Bases: PhaseSLM, Actuator

A mock version of a phase-only spatial light modulator. Some properties are available to simulate physical phenomena such as imperfect phase response, and front reflections (which cause non-modulated light).

property duration: Annotated[Quantity, Unit('ms')]

Maximum amount of time it takes to perform the measurement or for the actuator to stabilize.

This value does not include the latency.

For a detector, this is the maximum amount of time that elapses between returning from trigger() and the end of the measurement. For an actuator, this is the maximum amount of time that elapses from returning from a command like update() and the stabilization of the device.

If the duration of an operation is not known in advance, (e.g., when waiting for a hardware trigger), this function should return np.inf * u.ms.

Note

A device may update the duration dynamically. For example, a stage may compute the required time to move to the target position and update the duration accordingly.

Note

If latency is a (lower) estimate, the duration should be high enough to guarantee that latency + duration is at least as large as the time between starting the operation and finishing it.

property field: Detector

Returns an object to monitor the current state of the SLM.

If transient behavior is simulated, this is the effective field that is currently on the SLM.

property lookup_table: Sequence[int]

Lookup table that is used to map the wrapped phase range of 0-2pi to gray values (represented in a range from 0 to 256). By default, this is just range(256). Note that the lookup table need not contain 256 elements. A typical scenario is to use something like slm.lookup_table=range(142) to map the 0-2pi range to only the first 142 gray values of the slm.

property phase_response: ndarray | None

Phase as a function of pixel gray value.

This lookup table mimics the phase response of the SLM hardware. When it is omitted, the phase response is assumed to be linear: phase = 2 * pi * grey_value / 256

property phases: Detector

Returns an object to monitor the current state of the SLM.

If transient behavior is simulated, this is the effective phase that is currently on the SLM.

property pixels: Detector

Returns an object to monitor the current state of the SLM.

If transient behavior is simulated, these are the effective gray values that are currently displayed on the SLM.

refresh_rate
set_phases(values, update=True)[source]

Sets the phase pattern on the SLM.

Parameters:
  • values (ArrayLike) – phase pattern, in radians. The pattern is automatically stretched to fill the full SLM.

  • update – when True, calls update after setting the phase pattern. Set to False to suppress the call to update. This is useful in advanced scenarios where multiple parameters of the SLM need to be changed before updating the displayed image.

update()[source]

Sends the current phase image to the simulated SLM hardware.

class Shutter(source)[source]

Bases: Processor

A mock version of a shutter. When open, passes through the input field When closed, passes through the input field * 0.0

property open: bool
class SimulatedWFS(*, t=None, aberrations=None, slm=None, multi_threaded=True, beam_amplitude=1.0)[source]

Bases: Processor

A simple simulation of a wavefront shaping experiment.

Simulates a configuration where both the SLM and the aberrations are placed in the back pupil of a microscope objective, and a point detector is placed in the center of the focal plane.

The simulation computes (Σ A·exp(i·(aberrations-slm)))², which is the 0,0 component of the Fourier transform of the field in the pupil plane (including aberrations and the correction by the SLM).

For a more advanced (but slower) simulation, use Microscope

property data_shape: tuple

Returns the shape of the output data.

Returns:

tuple – The shape of the feedback signal, excluding the spatial dimensions.

class Stage(axis, step_size)[source]

Bases: Actuator

Mimics a single-axis stage actuator.

property axis: str
home()[source]
property position: Annotated[Quantity, Unit('um')]
property step_size: Annotated[Quantity, Unit('um')]
class StaticSource(data, *, pixel_size=None, extent=None, latency=<Quantity 0. ms>, duration=<Quantity 0. ms>, multi_threaded=None)[source]

Bases: Detector

Detector that returns pre-set data. Also simulates latency and measurement duration.

property data

The pre-set data to be returned by the mock source.

Note

The data is not copied. When setting the data property, the data_shape attribute is updated accordingly. If the data property is set with an array that has the pixel_size metadata set, the pixel_size attribute is also updated accordingly.

class XYStage(step_size_x, step_size_y)[source]

Bases: Actuator

Mimics an XY stage actuator

home()[source]
property step_size_x: Annotated[Quantity, Unit('um')]
property step_size_y: Annotated[Quantity, Unit('um')]
property x: Annotated[Quantity, Unit('um')]
property xy: tuple[Quantity, Quantity]
property y: Annotated[Quantity, Unit('um')]