slmsuite.holography.algorithms.SpotHologram#
- class SpotHologram(shape, spot_vectors, basis='kxy', spot_amp=None, cameraslm=None, null_vectors=None, null_radius=None, null_region=None, null_region_radius_frac=None, **kwargs)[source]#
Bases:
FeedbackHologramHolography optimized for the generation of optical focal arrays (DFT-based).
Is a subclass of
FeedbackHologram, but falls back to non-camera-feedback routines ifcameraslmis not passed.Tip
Quality of life features to generate noise regions for mixed region amplitude freedom (MRAF) algorithms are supported. Specifically, set
null_regionparameters to help specify where the noise region is not.- spot_knm#
Spot locations in the
"knm"(computational k-space) basis, stored as float vectors with shape(2, N)in the style offormat_2vectors().- Type:
array_like of float
- spot_kxy#
Spot locations in the
"kxy"basis, autocomputed from the others.- Type:
array_like of float OR None
- spot_ij#
Spot locations in the
"ij"(camera) basis, autocomputed from the others.Noneif the necessary transformations do not exist.- Type:
array_like of float OR None
- spot_knm_rounded#
spot_knmrounded to nearest integers (indices). These vectors are integers. This is necessary because GS algorithms operate on a pixel grid, and the target for each spot in aSpotHologramis a single pixel (index).- Type:
array_like of int
- spot_kxy_rounded#
Once
spot_knm_roundedis rounded, the originalspot_kxyis no longer accurate. Transformations are again used to backcompute the position in the"kxy"basis corresponding to the true computational location of a given spot.- Type:
array_like of float
- spot_ij_rounded#
As
spot_kxy_rounded, but in the"ij"basis. These vectors are floats.- Type:
array_like of float
- spot_amp#
The amplitudes to target for each spot. The target powers are the square of the amplitudes. Must have length corresponding to the number of spots. For instance, the user can request dimmer or brighter spots.
- Type:
array_like of float
- external_spot_amp#
When using
"external_spot"feedback or the"external_spot"stat group, the user must supply external data. This data is transferred through this attribute. For iterative feedback, have thecallback()function setexternal_spot_ampdynamically. By default, this variable is set to a copy ofspot_amp.- Type:
array_like of float
- spot_integration_width_knm#
For spot-specific feedback methods, better SNR is achieved when integrating over many farfield pixels. This variable stores the width of the integration region in
"knm"(farfield) space.- Type:
- null_knm#
In addition to points where power is desired,
SpotHologramis equipped with quality of life features to select points where power is undesired. These points are stored innull_knmwith shape(2, M)in the style offormat_2vectors(). A region around these points is set to zero (null) and not allowed to participate in the noise region.- Type:
array_like of float OR None
- null_radius_knm#
The radius in
"knm"space around the pointsnull_knmto zero or null (prevent from participating in thenannoise region). This is useful to prevent power being deflected to very high orders, which are unlikely to be properly represented in practice on a physical SLM.- Type:
- null_region_knm#
Array of shape
shape. WhereTrue, sets the background to zero instead ofnan. IfNone, has no effect.- Type:
array_like of bool OR
None
Methods
Collects the current nearfield amplitude regardless of np/cp configuration.
Collects the current complex DFT farfield, potentially with transformations.
Return this object's log records (only), as a list of plain-text strings.
Helper function to get the cupy memory pool size.
Helper function to calculate the shape of the computational space.
Collects the current nearfield phase from the GPU with
cupy.ndarray.get().Returns the current weights.
Convert an image in the camera domain to computational SLM k-space using, in part, the affine transformation stored in a cameraslm's Fourier calibration.
Uses
load_h5()to import the statistics hierarchy from a given h5 file.Log the current values of all tracked attributes.
Helper function to initialize a rectangular 2D array of spots, with certain size and pitch.
Method to request a measurement to occur.
Optimizes to solve the "phase problem": approximating the nearfield phase that transforms a known nearfield source amplitude to a desired farfield target amplitude.
Gradient-based iterative phase retrieval via
torchautograd and atorch.optimoptimizer (the"CG"method; seeoptimize()).GPU-accelerated Gerchberg-Saxton (GS) iterative phase retrieval.
Returns a dictionary containing selected attributes of this class.
Plots an overview (left) and zoom (right) view of
source.Plots the amplitude (left) and phase (right) of the nearfield (plane of the SLM).
Plots the statistics contained in the given dictionary.
Hones the positions of the produced spots toward the desired targets to compensate for Fourier calibration imperfections.
Spot holograms do not need to consider vortices.
Resets the hologram to an initial state.
Randomize or set the phase.
Resets the hologram weights to the
targetdefaults.Saves the dictionary returned from
pickle()to a file like"path/name_id.h5".Uses
save_h5()to export the statistics hierarchy to a given h5 file.Helper function to set the cupy memory pool size.
From the spot locations stored in
spot_knm, update the target pattern.Sets the weights to a new value.
Attributes
Width in camera pixels of the square region integrated around each spot for
"experimental_spot"feedback.- __init__(shape, spot_vectors, basis='kxy', spot_amp=None, cameraslm=None, null_vectors=None, null_radius=None, null_region=None, null_region_radius_frac=None, **kwargs)[source]#
Initializes a
SpotHologramtargeting given spots atspot_vectors.- Parameters:
shape ((int, int)) – Computational shape of the SLM. See
Hologram.__init__().spot_vectors (array_like) – Spot position vectors with shape
(2, N)in the style offormat_2vectors().basis (str) –
The spots can be in any of the following bases:
"kxy"for centered normalized SLM \(k\)-space (radians),"knm"for computational SLM \(k\)-space (pixels),"ij"for camera coordinates (pixels).
Defaults to
"kxy".spot_amp (array_like OR None) – The amplitudes to target for each spot. The target powers are the square of the amplitudes. See
spot_amp. IfNone, all spots are assumed to have the same amplitude. Normalization is performed automatically; the user is not required to normalize.cameraslm (
FourierSLMOR None) – If the"ij"or"kxy"bases are chosen, and/or if the user wants to make use of camera feedback, aslmsuite.hardware.cameraslms.FourierSLMmust be provided.null_vectors (array_like OR None) – Null position vectors with shape
(2, N)in the style offormat_2vectors(). MRAF methods are forced zero around these points.null_radius (float OR None) – Radius to null around in the given
basis. Note that basis conversions are imperfect for anisotropic basis transformations. The radius will always be set to be circular in"knm"space, and will attempt to match to the closest circle to the (potentially elliptical) projection into"knm"from the givenbasis.null_region (array_like OR None) – Array of shape
shape. WhereTrue, sets the background to zero instead ofnan. IfNone, has no effect.null_region_radius_frac (float OR None) – Helper function to set the
null_regionto zero for Fourier space radius fractions abovenull_region_radius_frac. This is useful to prevent power being deflected to very high orders, which are unlikely to be properly represented on a physical SLM. IfNone, defaults to \(\sqrt{2}\) (circumscribing the square farfield in fractional units) and there is no null region.**kwargs – Passed to
FeedbackHologram.__init__().
- get_amp()[source]#
Collects the current nearfield amplitude regardless of np/cp configuration.
- Returns:
Nearfield amplitude.
- Return type:
- get_farfield(shape=None, propagation_kernel=None, affine=None, get=True)[source]#
Collects the current complex DFT farfield, potentially with transformations. This includes collecting the data from the GPU with
cupy.ndarray.get().- Parameters:
shape ((int, int)) – Shape of the DFT. Useful to change the resolution of the farfield. If
None, defaults toshape, and falls back toslm_shape.propagation_kernel (array_like) – Used to check the result of the hologram at different depths. See
propagation_kernel. IfNone, defaults topropagation_kernelif one is present. Otherwise, no kernel is applied. Zeroing can force no kernel to be applied and yield the raw DFT.affine (dict) – Affine transformation to apply to farfield data (in the form of a dictionary with keys
"M"and"b"). IfNone, no transformation is applied.get (bool) – Whether or not to convert the cupy array to a numpy array if cupy is used. This is ignored if numpy is used.
- Returns:
Current farfield expected from the current
phase.- Return type:
- get_log(verbose=False)[source]#
Return this object’s log records (only), as a list of plain-text strings.
- Parameters:
verbose (bool, optional) – If
True, also print the records to the console.
- static get_mempool_limit(device=0)[source]#
Helper function to get the cupy memory pool size.
- static get_padded_shape(slm_shape, padding_order=1, square_padding=True, precision=inf, precision_basis='kxy')[source]#
Helper function to calculate the shape of the computational space. For a given base
slm_shape, pads to the user’s requirements. If the user chooses multiple requirements, the largest dimensions for the shape are selected. By default, pads to the smallest square power of two that encapsulates the originalslm_shape.See also
Note
Under development: a parameter to pad based on available memory (see
_calculate_memory_constrained_shape()).- Parameters:
slm_shape ((int, int) OR
FourierSLMORSLM) – The original shape of the SLM innumpy(h, w)form. The user can pass aFourierSLMorSLMinstead, and should pass this when using theprecisionparameter.padding_order (int) – Scales to the
padding_orderth larger power of 2. Apadding_orderof zero does nothing. For instance, withsquare_padding=False, an SLM with shape(720, 1280)would yield(720, 1280)forpadding_order=0,(1024, 2048)forpadding_order=1, and(2048, 4096)forpadding_order=2.square_padding (bool) – If
True, sets the smaller shape dimension to that of the larger, yielding a square.precision (float) – Returns the shape that produces a computational k-space with resolution smaller than
precision. The default, infinity, requests a padded shape larger than zero, sopadding_orderwill dominate.precision_basis (str) – Basis for the precision. Can be
"ij"(camera) or"kxy"(normalized blaze).
- Returns:
Shape of the computational space which satisfies the above requirements.
- Return type:
- get_phase(include_propagation=False)[source]#
Collects the current nearfield phase from the GPU with
cupy.ndarray.get(). Also offsets by \(\pi\), which shifts the \([-\pi, \pi]\) range ofnumpy.arctan2()to \([0, 2\pi]\) for faster writing to the SLM (seeset_phase()). The result is not wrapped, so a phase from CG, a quadratic initialization, or an includedpropagation_kernelcan fall outside this range.- Parameters:
include_propagation (bool) – Whether to include the
propagation_kernel, if available.- Returns:
Current nearfield phase of the optimization.
- Return type:
- get_weights()[source]#
Returns the current weights. Collects the current weights from the GPU if applicable.
- ijcam_to_knmslm(img, out=None, blur_ij=None, order=3, roi=None)[source]#
Convert an image in the camera domain to computational SLM k-space using, in part, the affine transformation stored in a cameraslm’s Fourier calibration.
Note
This includes two transformations:
The affine transformation
"ij"->"kxy"(camera pixels to normalized k-space).The scaling
"kxy"->"knm"(normalized k-space to computational k-space pixels).
- Parameters:
img (numpy.ndarray OR cupy.ndarray) – Image to transform. This should be the same shape as images returned by the camera, unless
roiis given (see below).out (numpy.ndarray OR cupy.ndarray OR None) – If
outis notNone, this array will be used to write the memory in-place.blur_ij (int OR None) – Applies a
blur_ijpixel-width Gaussian blur toimg. IfNone, defaults to the"blur_ij"flag if present; otherwise zero. Withroi, the blur is applied within the sub-image.order (int) – Order of interpolation used for transformation. Defaults to 3 (cubic).
Region of interest, as the
(y, x)camera pixel thatimg[0, 0]corresponds to. When given,imgis a sub-image of the camera frame rather than a full frame, and everything outside it is undefined (asnumpy.nanpadding would be). Only the sub-image is uploaded to the GPU, which is much cheaper than embedding it in a camera-sized canvas. IfNone,imgcovers the full camera frame.Source coordinates in the outer half-pixel rim of the sub-image are undefined, so leave a pixel of margin around the signal. Above
order=0, the spline prefilter makes the result differ slightly from a full-frame transform.
- Returns:
Image transformed into
"knm"space.- Return type:
numpy.ndarray OR cupy.ndarray
- load_stats(file_path, include_state=True)[source]#
Uses
load_h5()to import the statistics hierarchy from a given h5 file.
- log_state(level=10)[source]#
Log the current values of all tracked attributes.
- Parameters:
level (int, optional) – Logging level. Defaults to
logging.DEBUG.
- static make_rectangular_array(shape, array_shape, array_pitch, array_center=None, basis='knm', orientation_check=False, spot_amp=None, **kwargs)[source]#
Helper function to initialize a rectangular 2D array of spots, with certain size and pitch.
Note
The array can be in SLM k-space coordinates or in camera pixel coordinates, depending upon the choice of
basis. For the"ij"basis,cameraslmmust be included as one of thekwargs. See__init__()for morebasisinformation.Important
Spot positions will be rounded to the grid of computational k-space
"knm", to create the target image (of finite size) that algorithms optimize towards. Choosearray_pitchandarray_centercarefully to avoid undesired pitch non-uniformity caused by this rounding.- Parameters:
shape ((int, int)) – Computational shape of the SLM in
numpy(h, w) form. SeeSpotHologram.__init__().array_shape ((int, int) OR int) – The size of the rectangular array in number of spots
(NX, NY). If a scalar N is given, assume(N, N).array_pitch ((float, float) OR float) – The spacing between spots in the x and y directions
(pitchx, pitchy). If a single pitch is given, assume(pitch, pitch).array_center ((float, float) OR None) –
The shift of the center of the spot array from the zeroth order. Uses
(x, y)form in the chosen basis. IfNone, defaults to the position of the zeroth order, converted into the relevant basis:If
"knm", this is(shape[1], shape[0])/2.If
"kxy", this is(0,0).If
"ij", this is the pixel position of the zeroth order on the camera (calculated via Fourier calibration).
basis (str) – See
__init__().orientation_check (bool) – Whether to delete the last two points to check for parity.
spot_amp (array_like OR None) – See
spot_amp, in the order that the grid is raveled. Trimmed alongside the points thatorientation_checkdeletes.**kwargs – Any other arguments are passed to
__init__().
- measure(basis='ij')[source]#
Method to request a measurement to occur. If
img_ijisNone, then a new image will be grabbed from the camera (this is done automatically in algorithms).
- optimize(method='GS', maxiter=20, verbose=True, callback=None, feedback=None, stat_groups=None, **kwargs)[source]#
Optimizes to solve the “phase problem”: approximating the nearfield phase that transforms a known nearfield source amplitude to a desired farfield target amplitude. Supported optimization methods include:
Gerchberg-Saxton (GS) phase retrieval.
'GS'An iterative algorithm for phase retrieval, accomplished by moving back and forth between the imaging and Fourier domains, with amplitude corrections applied to each. This is usually implemented using fast discrete Fourier transforms, potentially GPU-accelerated.
Weighted Gerchberg-Saxton (WGS) phase retrieval algorithms of various flavors. Improves the uniformity of GS-computed focus arrays using weighting methods and techniques from literature. The
methodkeywords are:'WGS-Leonardo'The original WGS algorithm. Weights the target amplitudes by the ratio of mean amplitude to computed amplitude, which amplifies weak spots while attenuating strong spots. Uses the following weighting function:
\[\mathcal{W} = \mathcal{W}\left(\frac{\mathcal{T}}{\mathcal{F}}\right)^p\]where \(\mathcal{W}\), \(\mathcal{T}\), and \(\mathcal{F}\) are the weight amplitudes, target (goal) amplitudes, and feedback (measured) amplitudes, and \(p\) is the power passed as
"feedback_exponent"inflags(seekwargs). The power \(p\) defaults to .8 if not passed. In general, smaller \(p\) will lead to slower yet more stable optimization.'WGS-Kim'Improves the convergence of
WGS-Leonardoby fixing the farfield phase strictly after a desired number of net iterations specified by"fix_phase_iteration"or after exceeding a desired efficiency (fraction of farfield energy at the desired points) specified by"fix_phase_efficiency"'WGS-Nogrette'Weights target intensities by a tunable gain factor.
\[\mathcal{W} = \mathcal{W}\Big/\left(1 - f\left(1 - \frac{\mathcal{F}/\mathcal{T}}{\langle\mathcal{F}/\mathcal{T}\rangle}\right)\right)\]where \(\langle\cdot\rangle\) is the mean and \(f\) is the gain factor passed as
"feedback_factor"inflags(seekwargs). The factor \(f\) defaults to .1 if not passed.Note that while Nogrette et al. compare powers, this implementation compares amplitudes for speed. These are identical to first order.
'WGS-Wu'Weights using an exponential function, which is less sensitive to near-zero values of \(\mathcal{F}\) or \(\mathcal{T}\).
\[\mathcal{W} = \mathcal{W}\exp\left( p (\mathcal{T} - \mathcal{F}) \right)\]The speed of correction is controlled by \(p\), the power passed as
"feedback_exponent".'WGS-tanh'Weights by hyperbolic tangent, commonly used as an activation function in machine learning.
\[\mathcal{W} = \mathcal{W}\left[1 + f\text{tanh}\left( p (\mathcal{T} - \mathcal{F}) \right) \right]\]This weighting limits each update to a relative change of \(\pm f\), passed as
"feedback_factor", which is useful to prevent large changes. The speed of correction is controlled by \(p\), the power passed as"feedback_exponent".
Conjugate Gradient (CG) phase retrieval.
'CG'(This feature is experimental.)
Some holography—especially that with more complicated holographic objectives—can be better treated with gradient-based methods. In these cases, the phase is guided to an optimized state by following the back-propagated gradients (with respect to phase) of given objective
losswhich is passed as one of theflagstooptimize(). Weighting different components of the objective leads to tradeoffs between those components: for instance a tradeoff between power guided into a given pattern and the uniformity of the realized pattern.slmsuiteusestorchas a backend for gradient computation. Notably, memory is still owned and initialized bycupy, but gradients can be calculated by usingtorch-cupyinteroperability.The objective
lossis expected to be atorch.nn.Moduleand defaults to a complex variant oftorch.nn.MSELoss()that skips undefined (nan) target pixels, such as an MRAF noise region, but normalizes the farfield over the whole plane.lossis called in the style oftorch, using (as arguments) the computedfarfield(with gradient tree intact) and thetargetvalues for the farfield. Internally, this looks like:result = loss( # The user provides this nn.Module to .optimize() farfield, # The farfield (with gradients), calculated from `phase` by slmsuite target # The target, initialized by the user and processed by slmsuite ) result.backward() # Gradients are back-propagated to the input `phase`.
For
FeedbackHologramand subclasses, the gradients are computed computationally, but the computational values are then replaced with the experimental results. This allows optimization of the experimental results using the computational gradients (correct to first order) as a guide. Pixels the camera does not see are passed as undefined target pixels, so anull_regionthere is not enforced, and a target pixel the camera reads as zero passes no gradient: start from a computational solution. Currently, feedback is not supported for spot arrays with"experimental_spot"or"computational_spot"feedback (WGS probably works better for such spot array objectives anyway).Creating a custom objective is as simple as making a custom
torch.nn.Module.forward()method. These methods can be as simple as a single expression or as complicated as a full neural network operating on the input parameters. However, remember to usetorchmethods because the arguments are of typetorch.Tensor. Here’s an example of a customtorch.nn.Module.forward()which implements the Huber loss:# Define the loss as a class. class HuberLoss(nn.Module): def __init__(self, delta=1.0): super(HuberLoss, self).__init__() self.delta = delta def forward(self, farfield, target): residual = torch.abs(farfield - target) quadratic = torch.clamp(residual, max=self.delta) linear = residual - quadratic loss = 0.5 * quadratic ** 2 + self.delta * linear return torch.mean(loss) # Initialize the class. Remember that we can pass arguments (delta) here. loss = HuberLoss(delta=2.0) # Pass the loss to the hologram by one of two methods: hologram.optimize(..., loss=loss) # 1. Pass as **kwarg. hologram.flags["loss"] = loss # 2. Set directly.
MRAF (next section), if desired, needs to be handled by the
lossfunction. MRAF information is encoded in thetarget, with the noise region beingnan.
The option for Mixed Region Amplitude Freedom (MRAF) feedback. In standard iterative algorithms, the entire Fourier-domain unpatterned field is replaced with zeros. This is disadvantageous because a desired farfield pattern might not be especially compatible with a given nearfield amplitude, or otherwise. MRAF enables “noise regions” where some fraction of the given farfield is not replaced with zeros and instead is allowed to vary. In practice, MRAF is enabled by setting parts of the
targettonan; these regions act as the noise regions. The"mraf_factor"flag inflagsallows the user to partially attenuate the noise regions. A factor of 0 fully attenuates the noise region (normal WGS behavior). A factor of 1 does not attenuate the noise region at all (the default). Middle ground is recommended, but is application-dependent as a tradeoff between improving pattern fidelity and maintaining pattern efficiency. Setting the"mraf"flag toFalsedisables MRAF even when the target containsnan. With MRAF enabled, a nonzero"zero_factor"flag \(f_0\) replaces the zeroing of zero-target pixels with an accumulated correction \(\mathcal{W}_0 \leftarrow \mathcal{W}_0 - f_0|E|E\), where \(E\) is the complex farfield there (default 0, zeroing).As examples, consider two cases where MRAF can be useful:
Sloping a top hat. Suppose we want very flat amplitude on a beam. Requesting a sharp edge to this beam can lead to fringing effects at the boundary which mitigate flatness both inside and outside the beam. If instead a noise region is defined in a band surrounding the beam, the noise region will be filled with whatever slope best enables the desired flat beam.
Mitigating diffractive orders. Without MRAF, spot patterns with high crystallinity often have “ghost” diffractive orders which continue the pattern past the edges of requested spots. Even though these orders are attenuated during each phase retrieval iteration, they remain part of the best solution for the recovered phase. With MRAF, a noise region can help solve for retrieved phase which does not generate these undesired orders.
Caution
Requesting
stat_groupswill slow the speed of optimization due to the overhead of processing and saving statistics, especially in the case of GPU-accelerated optimization where significant time cost is incurred by moving these statistics to the CPU. This is especially apparent in the case of fully-computational holography, where this effect can slow what is otherwise a fully-GPU-contained loop by an order of magnitude.Tip
This function uses a parameter naming convention borrowed from
scipy.optimize.minimize()and other functions inscipy.optimize. The parametersmethod,maxiter, andcallbackhave the same functionality as the equivalently-named parameters inscipy.optimize.minimize().- Parameters:
method (str) – Optimization method to use. See the list of optimization methods above.
maxiter (int) – Number of iterations to optimize before terminating.
verbose (bool OR int) – Whether to display
tqdmprogress bars. These bars are also not displayed formaxiter <= 1.callback (callable OR None) – Same functionality as the equivalently-named parameter in
scipy.optimize.minimize().callbackmust accept a Hologram or Hologram subclass as the single argument. IfcallbackreturnsTrue, then the optimization exits. Ignored ifNone. When applying"external_spot"feedback, this callback is the place to update the"external_spot_amp"attribute.feedback (str OR None) –
Type of feedback to use during optimization, for instance when weighting in
"WGS". For direct instances ofHologram, this can only be"computational"feedback. Subclasses support more types of feedback. Supported feedback options include the following:"computational"Uses the projected farfield pattern (transform of the complex nearfield) as feedback."experimental"Uses a camera contained in a passedcameraslmas feedback. Specific to subclasses ofFeedbackHologram."computational_spot"Takes the computational result (the projected farfield pattern) and integrates regions around the expected positions of spots in an optical focus array. More stable than"computational"for spots. Specific to subclasses ofSpotHologram."experimental_spot"Takes the experimental result (the image from a camera) and integrates regions around the expected positions of spots in an optical focus array. More stable than"experimental"for spots. Specific to subclasses ofSpotHologram."external_spot"Uses some external user-provided metric for spot feedback. SeeSpotHologram.external_spot_amp. Usually applied duringcallback. Specific to subclasses ofSpotHologram.
stat_groups (list of str OR None) – Strings representing types of feedback (data gathering) upon which statistics should be derived. These strings correspond to valid types of feedback (see above). For instance, if
"experimental"is passed as a stat group, statistics on the pixels in the experimental feedback image will automatically be computed and stored for each iteration of optimization. However, this comes with overhead (see above warning).**kwargs (dict, optional) – Various weight keywords and values to pass depending on the weight method. These are passed into
flags. See options documented in the constructor. Flags read byreset_phase(), such asquadratic_phase, are stored too, but have no effect untilreset_phase()is next called. The exception isname, which labels thetqdmprogress bar and is not stored.
- optimize_cg(iterations, callback)[source]#
Gradient-based iterative phase retrieval via
torchautograd and atorch.optimoptimizer (the"CG"method; seeoptimize()).(This feature is experimental.)
Solves the “phase problem”: approximates the nearfield phase that transforms a known nearfield source amplitude to a desired farfield target amplitude.
Caution
This function should be called through
optimize()and not called directly. It is left as a public function exposed in documentation to clarify how the internals ofoptimize()work.Caution
This method does not currently support
"experimental_spot"or"external_spot"feedback.- Parameters:
iterations (iterable) – Number of loop iterations to run. Is an iterable to pass a
tqdmiterable.callback (callable OR None) – See
optimize().
- optimize_gs(iterations, callback)[source]#
GPU-accelerated Gerchberg-Saxton (GS) iterative phase retrieval.
Solves the “phase problem”: approximates the nearfield phase that transforms a known nearfield source amplitude to a desired farfield target amplitude.
Caution
This function should be called through
optimize()and not called directly. It is left as a public function exposed in documentation to clarify how the internals ofoptimize()work.- Parameters:
iterations (iterable) – Number of loop iterations to run. Is an iterable to pass a
tqdmiterable.callback (callable OR None) – See
optimize().
- 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. IfTrue, also pickles ‘heavy’ attributes such as large images and calibrations. Iflist 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 formatted as a floating point timestamp. This information is used as standard metadata for calibrations and saving.
- plot_farfield(source=None, title='', limits=None, units='knm', limit_padding=0.1, figsize=(8, 4), cbar=False, axs=None)[source]#
Plots an overview (left) and zoom (right) view of
source.- Parameters:
source (array_like OR None) – Should have shape equal to
shape. IfNone, defaults toamp_ff.title (str) – Title of the plots. If
"phase"is a substring of title, then the source is treated as a phase.limits (((float, float), (float, float)) OR None) – \(x\) and \(y\) limits for the zoom plot in
"knm"space. If None,limitsare autocomputed as the smallest bounds that show all non-zero values (pluslimit_padding). Note that autocomputing ontargetwill perform well, as zero values are set to actually be zero. However, doing so on computational or experimental outputs (e.g.amp_ff) will likely perform poorly, as values in the field deviate slightly from zero and artificially expand thelimits.units (str) – Far-field units for plots (see
convert_vector()for options). If units requiring a SLM are desired, the attributecameraslmmust be filled.limit_padding (float) – Fraction of the width and height to expand the limits of the zoom plot by, only if the passed
limitsisNone(autocompute).figsize (tuple) – Size of the plot.
cbar (bool) – Whether to add colorbars to the plots. Defaults to
False.axs (matplotlib.axes.Axes OR None) – If provided, uses these axes instead of creating new ones.
- Returns:
Used
limits, which may be autocomputed. Autocomputed limits are returned as integers.- Return type:
- plot_nearfield(source=None, title='', padded=False, figsize=(8, 4), cbar=False)[source]#
Plots the amplitude (left) and phase (right) of the nearfield (plane of the SLM). The amplitude is assumed (whether uniform, assumed, or measured) while the phase is the result of optimization.
- Parameters:
source (array_like OR None) – Source to plot. If
None, defaults to the current amplitude and phase.title (str) – Title of the plots.
padded (bool) – If
True, shows the full computational nearfield of shapeshape. Otherwise, shows the region at the center of the computational space of sizeslm_shapecorresponding to the unpadded SLM.figsize (tuple) – Size of the plot.
cbar (bool) – Whether to add colorbars to the plots. Defaults to
False.
- plot_stats(stats_dict=None, stat_groups=None, ylim=None, show=False)[source]#
Plots the statistics contained in the given dictionary.
- Parameters:
stats_dict (dict OR None) – Stats to plot in dictionary form. If
None, defaults tostats.stat_groups (list of str OR None) – Which statistics groups to plot. If empty or
Noneis provided, defaults to all groups present instats.ylim ((int, int) OR None) – Allows the user to pass in desired y limits. If
None, the default y limits are used.show (bool) – Whether or not to immediately show the plot. Defaults to
False.
- refine_offset(img=None, basis='kxy', force_affine=True, plot=False)[source]#
Hones the positions of the produced spots toward the desired targets to compensate for Fourier calibration imperfections. Works either by moving camera integration regions to the positions where the spots ended up (
basis="ij") or by moving the \(k\)-space targets to target the desired camera pixels (basis="knm"/basis="kxy"). This should be run at the user’s request betweenoptimize()iterations.- Parameters:
img (numpy.ndarray OR None) – Image measured by the camera. If
None, defaults toimg_ijviameasure().basis (str) –
The correction can be in any of the following bases:
"ij"changes the pixel that the spot is expected at,"kxy","knm"change the k-vector which the SLM targets.
Defaults to
"kxy". If basis is set toNone, no correction is applied to the data in theSpotHologram.force_affine (bool) – Whether to force the offset refinement to behave as an affine transformation between the original and refined coordinate system. This helps to tame outliers. Defaults to
True.plot (int OR bool) – Enables debug plots at
1and above.
- Returns:
Spot shift in the
"ij"basis for each spot.- Return type:
- reset(reset_phase=True, reset_flags=False, reset_weights=True)[source]#
Resets the hologram to an initial state. Does not restore the preconditioned
phasethat may have been passed to the constructor (as this information is lost upon optimization). Instead, phase is randomized ifreset_phase=True. Also uses the currenttargetrather than thetargetthat may have been passed to the constructor (e.g. includes currentrefine_offset()changes, etc).- Parameters:
reset_phase (bool) – Whether to additionally call
reset_phase().reset_flags (bool) – Whether to erase the information (including passed
kwargs) stored inflags.reset_weights (bool) – Whether to additionally call
reset_weights(). PassFalsewhen the caller has already re-derived the weights from the currenttarget.
- save(path='.', name=None, **kwargs)[source]#
Saves the dictionary returned from
pickle()to a file like"path/name_id.h5".- Parameters:
- Returns:
The file path that the pickled data was saved to.
- Return type:
- save_stats(file_path, include_state=True)[source]#
Uses
save_h5()to export the statistics hierarchy to a given h5 file.Tip
Enabling the
"raw_stats"flag will save feedback data from each iteration instead of only derived statistics. Consider enabling this to save more detailed information.- Parameters:
file_path (str) – Full path to the file to write the data to.
include_state (bool) – If
True, also includes all other attributes ofHologramexcept fordtype(cannot pickle) andamp_ff(can regenerate). These attributes are converted tonumpyif necessary. Note that the intent is not to produce a runnableHologramby default (as this would require pickling hardware interfaces), but rather to provide extra information for debugging.
- static set_mempool_limit(device=0, size=None, fraction=None)[source]#
Helper function to set the cupy memory pool size.
- Parameters:
device (int) – Which GPU to set the limit on. Passed to
cupy.cuda.Device().size (int) – Desired number of bytes in the pool. Passed to
cupy.cuda.MemoryPool.set_limit().fraction (float) – Fraction of available memory to use. Passed to
cupy.cuda.MemoryPool.set_limit().
- set_target(reset_weights=False)[source]#
From the spot locations stored in
spot_knm, update the target pattern.Note
If there’s a
cameraslm, updates thespot_ij_roundedattribute corresponding to where pixels in the \(k\)-space were actually placed (due to rounding to integers, stored inspot_knm_rounded), rather than the idealized floatsspot_knm.Note
The
targetandweightsmatrices are modified in-place for speed, unlikeHologramorFeedbackHologramwhich make new matrices. This is because spot positions are expected to be corrected usingrefine_offset().
- set_weights(new_weights)[source]#
Sets the weights to a new value. Handles moving data onto the GPU if applicable.
- property spot_integration_width_ij[source]#
Width in camera pixels of the square region integrated around each spot for
"experimental_spot"feedback. Integrating over many camera pixels gives better SNR.Nonewhen the spots are not located on a camera.Setting this re-runs
_check_spots_in_frame(), as a width assigned after construction (aswavefront_calibrate_zernike()does) can push the integration regions off the frame.