slmsuite.holography.algorithms.Hologram#
- class Hologram(target, amp=None, phase=None, slm_shape=None, dtype=<class 'numpy.float32'>, propagation_kernel=None, **kwargs)[source]#
Bases:
HologramPhase retrieval methods applied to holography (DFT-based). See
optimize()to learn about the methods implemented for hologram optimization.Tip
The Fourier domain (
"kxy") of an SLM with shapeslm_shapealso has the shapeslm_shapeunder discrete Fourier transform. The extents of this domain correspond to the edges of the farfield determined by physical constants as \(\pm\frac{\lambda}{2\Delta x}\) radians, where \(\Delta x\) is the SLM pixel pitch. This means that resolution of the farfield \(\pm\frac{\lambda}{2N_x\Delta x}\) radians can be quite poor with small resolution \(N_x\). The solution is to zero-pad the SLM nearfield — artificially increasing the width \(N_x\) and height \(N_y\) while the extent of the non-zero nearfield data remains the same — and thus enhance the resolution of the farfield. In practice, padding is accomplished by passing ashapeortargetof appropriate shape (see constructor__init__()and subclasses), potentially with the aid of the static helper functionget_padded_shape().Note
target,weights,phase_ff, andamp_ffare all matrices of shapeshape. To save memory, the matricesphaseandampare stored with the (smaller, but not strictly smaller) shapeslm_shape. Also to save memory,phase_ffandamp_ffare set toNoneon construction, and only initialized if they need to be used. Any code additions should check forNone.Tip
Due to imperfect SLM diffraction efficiency, undiffracted light will be present at the center of the
target. This is called the zeroth order diffraction peak. To avoid this peak, consider shifting the data contained intargetaway from the center.Tip
For mixed region amplitude freedom (MRAF) capabilities, set the part of the
targetdesired as a ‘noise region’ tonan. Seeoptimize()for more details.SpotHologramhas spot-specific methods for generated noise region pattern.Caution
By default, arguments passed to the constructor (
phase,amp, … ) are stored directly as attributes without copying, when possible. These will be modified in place. However,numpyarrays passed tocupywill naturally be copied onto the GPU and arrays of incorrectdtypewill likewise be copied and casted. This lack of copying is desired in many cases, such that external routines access the same data, but the user can choose to pass copied arrays if this behavior is undesired.- slm_shape#
The shape of the nearfield device producing the hologram in the farfield in
numpy(h, w)form. This is important to record because certain optimizations and calibrations depend on it. If multiple ofslm_shape,phase, orampare notNonein the constructor, the shapes must agree. If all areNone, then the shape of thetargetis used instead (slm_shape==shape).- Type:
(int, int)
- shape#
The shape of the computational space in the nearfield and farfield in
numpy(h, w)form. Corresponds to the the"knm"basis in the farfield. This often differs fromslm_shapedue to padding of the nearfield.- Type:
(int, int)
- phase#
nearfield phase pattern to optimize. Initialized to with
random.default_rng().uniform()by default (None). This is of shapeslm_shapeand (upon copying tonearfieldduring optimization) padded to shapeshape.- Type:
numpy.ndarray OR cupy.ndarray
- amp#
nearfield source amplitude pattern (i.e. image-space constraints). Uniform illumination is assumed by default (
None). This is of shapeslm_shapeand (upon copying tonearfieldduring optimization) padded to shapeshape.- Type:
numpy.ndarray OR cupy.ndarray
- nearfield#
Helper variable to encode the data in
phaseandampas a single complex matrix. This is of shapeshape.- Type:
numpy.ndarray OR cupy.ndarray
- target#
Desired farfield amplitude in the
"knm"basis. The goal of optimization. This is of shapeshapein DFT-based algorithms, but differs forCompressedSpotHologram.- Type:
numpy.ndarray OR cupy.ndarray
- weights#
The mutable farfield amplitude in the
"knm"basis used in GS. Starts astargetbut may be modified by weighted feedback in WGS. This is of the same shape astarget.- Type:
numpy.ndarray OR cupy.ndarray
- farfield#
Helper variable to encode the data in the farfield as a single complex matrix. This is of the same shape as
target.- Type:
numpy.ndarray OR cupy.ndarray
- phase_ff#
Algorithm-constrained farfield phase in the
"knm"basis. Used as a helper variable for optimization. Stored for computational algorithms which desire to fix the phase in the farfield (seeoptimize_gs()). This is of the same shape astarget.- Type:
numpy.ndarray OR cupy.ndarray
- amp_ff#
Farfield amplitude in the
"knm"basis. Used for comparing this, the computational result, with thetarget. This is of the same shape astarget.- Type:
numpy.ndarray OR cupy.ndarray OR None
- dtype#
Datatype for real arrays. The default is
float32.- Type:
type
- dtype_complex#
Datatype for complex arrays. The complex numbers follow
numpytype promotion. Complex datatypes are derived fromdtype:float32->complex64(the defaultdtype)float64->complex128
float16is not recommended fordtypebecausecomplex32is not implemented bynumpy.- Type:
type
- propagation_kernel#
Allows the user to target holography at different depths or aberration spaces. This is also applied for
FeedbackHologramand subclasses to ~slmsuite.holography.algorithms.FeedbackHologram.measure() the hologram at the desired plane. IfNone, this feature is not used and no depth or aberration transformation is applied.- Type:
numpy.ndarray OR cupy.ndarray OR None
- iter#
Tracks the current iteration number.
- Type:
int
- flags#
Helper flags to store custom persistent variables for optimization. These flags are generally changed by passing as a
kwargtooptimize(). Contains the following keys:"method"strStores the method used for optimization. See
optimize().
"fixed_phase"boolFixes the farfield phase as mandated by certain weighted algorithms (see
optimize_gs()).
"feedback"strStores the values passed to
optimize().
"stat_groups"list of strStores the values passed to
optimize().
"raw_stats"boolWhether to store raw stats: the raw image and feedback data for each iteration. Note that this can be a good amount of data.
"blur_ij"floatSee
ijcam_to_knmslm().
Other user-defined flags.
- Type:
dict
- stats#
Dictionary of useful statistics. data is stored in lists, with indices corresponding to each iteration. Contains:
"methods"list of strMethod used for each iteration.
"flags"dict of listsEach key corresponds to a flag that was used at least once. If it is
np.nanon a given iteration, then it was undefined at that point (update functions keep track of all this).
"stats"dict of dicts of listsSame format as
"flags", except with another layer of hierarchy corresponding to the source (group) of the given stats. This is to differentiate standard deviations computed computationally and experimentally.
See
_update_stats()andplot_stats().- Type:
dict
Methods
Collects the current complex DFT farfield, potentially with transformations.
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().Uses
save_h5()to import the statistics hierarchy from a given h5 file.Optimizers to solve the "phase problem": approximating the nearfield phase that transforms a known nearfield source amplitude to a desired farfield target amplitude.
Conjugate Gradient (CG) iterative phase retrieval.
GPU-accelerated Gerchberg-Saxton (GS) iterative phase retrieval.
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.
Removes the computed phase vortices in the farfield where the target amplitude is positive.
Resets the hologram to an initial state.
Resets the hologram to a provided phase, to a random state, or to a quadratic phase which overlaps with the target pattern.
Resets the hologram weights to the
targetdefaults.Uses
save_h5()to export the statistics hierarchy to a given h5 file.Change the target to something new.
- __init__(target, amp=None, phase=None, slm_shape=None, dtype=<class 'numpy.float32'>, propagation_kernel=None, **kwargs)[source]#
Initialize datastructures for optimization. When
cupyis enabled, arrays are initialized on the GPU ascupyarrays: take care to use class methods to access these parameters instead of editing them directly, ascupyarrays behave slightly differently than numpy arrays in some cases.Parameters additional to class attributes are described below:
- Parameters:
target (numpy.ndarray OR cupy.ndarray OR (int, int) OR None) – Target to optimize to. The user can also pass a shape in
numpy(h, w)form, and this constructor will create an empty target of all zeros.get_padded_shape()can be of particular help for calculating the shape that will produce desired results (in terms of precision, etc).Noneis used internally.amp (array_like OR None) – The nearfield amplitude. See
amp. Of shapeslm_shape.phase (array_like OR None) – The nearfield initial phase. See
phase.phaseshould only be passed if the user wants to precondition the optimization. Of shapeslm_shape.slm_shape ((int, int) OR slmsuite.hardware.FourierSLM OR slmsuite.hardware.slms.SLM OR None) – The shape of the nearfield of the SLM in
numpy(h, w) form. Optionally, as a quality of life feature, the user can pass aFourierSLMorSLMinstead, andslm_shape(andampif it isNone) are populated from this. IfNone, tries to use the shape ofamporphase, but if these are not present, defaults toshape(which is usually determined bytarget).dtype (type) – See
dtype; the type to use for stored arrays. The user should choose this as a tradeoff between precision, memory size, and compute time.propagation_kernel (array_like OR None) –
Primarily used for targeting holography at a different depth plane, encoded by a focusing kernel.
MultiplaneHologram, targeting several depth planes, must make use of this parameter to ‘bake’ the information for each plane into the composite hologram. A more advanced use of this feature is to target different positions in aberration-space, i.e. have a unique wavefront calibration baked into the hologram for each plane.The kernel must be of shape
slm_shape. IfNone, this feature is unused (the kernel is an ideal DFT).Tip
The unit conversions necessary to convert a depth into a Zernike focusing parameter are stored in a
cameraslm, and can be accessed viaconvert_vector().# Convert a floating point Z depth from a desired units to Zernike units. depth_zernike = convert_vector( (0, 0, depth), from_units="{depth_units}", to_units="zernike", hardware=cameraslm, ) # The ANSI Zernike indices (2,1,4) [x,y,z] # are automatically assumed from the 3-vector. propagation_kernel = toolbox.phase.zernike_sum( grid=cameraslm, weights=depth_zernike, )
Note
Is ignored for
CompressedSpotHologram.**kwargs – Passed to
flags.
- 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:
numpy.ndarray
- static get_mempool_limit(device=0)[source]#
Helper function to get the cupy memory pool size.
- Parameters:
device (int) – Which GPU to set the limit on. Passed to
cupy.cuda.Device().- Returns:
Current memory pool limit in bytes
- Return type:
int
- 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 slmsuite.hardware.FourierSLM) – The original shape of the SLM in
numpy(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, 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:
(int, int)
- get_phase(include_propagation=False)[source]#
Collects the current nearfield phase from the GPU with
cupy.ndarray.get(). Also shifts the \([-\pi, \pi]\) range ofnumpy.arctan2()to \([0, 2\pi]\) for faster writing to the SLM (seeset_phase()).- Parameters:
include_propagation (bool) – Whether to include the
propagation_kernel, if available.- Returns:
Current nearfield phase of the optimization.
- Return type:
numpy.ndarray
- load_stats(file_path, include_state=True)[source]#
Uses
save_h5()to import the statistics hierarchy from a given h5 file.Tip
Enabling the
"raw_stats"flag will export feedback data from each iteration instead of only derived statistics. Consider enabling this to save more detailed information upon export.
- optimize(method='GS', maxiter=20, verbose=True, callback=None, feedback=None, stat_groups=[], **kwargs)[source]#
Optimizers 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}/\left(1 - f\left(1 - \mathcal{F}/\mathcal{T}\right)\right)\]where \(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 compares 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.slmsuiteusespytorchas a backend for gradient computation. Notably, memory is still owned and initialized bycupy, but gradients can be calculated by usingpytorch-cupyinteroperability.The objective
lossis expected to be atorch.nn.Moduleand defaults to a complex variant oftorch.nn.MSELoss().lossis called in the style ofpytorch, 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. 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 usepytorchmethods 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.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 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. Ifverboseis greater than 1, then flags are printed as a preamble.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.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 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. Seeexternal_spot_amp. 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.
- optimize_cg(iterations, callback)[source]#
Conjugate Gradient (CG) iterative phase retrieval.
(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.- 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.Note
Default FFTs are not in-place in this algorithm. In both non-
cupyandcupyimplementations,numpy.fftdoes not support in-place operations. However,scipy.fftdoes in both. In the future, we may move to the scipy implementation. However, neithernumpyorscipyfftshiftsupport in-place movement (for obvious reasons). For even faster computation, algorithms should consider not shifting the FFT result, and instead shifting measurement data / etc to this unshifted basis. We might also implement get_fft_plan for even faster FFTing. However, in practice, speed is limited by other peripherals (especially feedback and stats) rather than FFT speed or memory.- Parameters:
iterations (iterable) – Number of loop iterations to run. Is an iterable to pass a
tqdmiterable.callback (callable OR None) – See
optimize().
- plot_farfield(source=None, title='', limits=None, units='knm', limit_padding=0.1, figsize=(8, 4), cbar=False)[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.
- Returns:
Used
limits, which may be autocomputed. Autocomputed limits are returned as integers.- Return type:
((float, float), (float, float))
- 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, or experimentally computed) while the phase is the result of optimization.
- Parameters:
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=[], 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.
- remove_vortices(plot=False)[source]#
Removes the computed phase vortices in the farfield where the target amplitude is positive. Useful for smoothing out the pattern and reducing speckle. The user can call this method by passing a
callback=function containing it. For instance:# Define a function to use a callback. def remove_vortices_callback(holo): if holo.iter % 10 == 9: # Only remove vortices every 10 iterations. holo.remove_vortices() # This method is slightly expensive, so calling every loop is not advised. # The function will be called during the loop. hologram.optimize(..., callback=remove_vortices_callback)
Important
This callback can only applied be during a GS loop. To use for a conjugate gradient hologram, do a single iteration of GS.
- Parameters:
plot (bool) – Enable debug plots.
- reset(reset_phase=True, reset_flags=False)[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_phase(custom_phase=None, random_phase=None, quadratic_phase=None)[source]#
Resets the hologram to a provided phase, to a random state, or to a quadratic phase which overlaps with the target pattern.
- Parameters:
custom_phase (array_like OR None) – Custom nearfield initial phase. If not
None, then all other parameters are ignored. Seephase.phaseshould only be passed if the user wants to precondition the optimization. Of shapeslm_shape.random_phase (float OR None) – Sets the phase to uniformly random phase, scaled to \(2\pi\). Setting
random_phaseto a fraction of 1 likewise scales the randomness. IfNone, looks for"random_phase"inflags. This adds with thequadratic_phaseparameter.quadratic_phase (bool OR float OR None) – We can also precondition the phase analytically (with a lens and blaze) to roughly the size of the target hologram, according to the first and second order
image_moments(). This quadratic preconditioning is thought to help reduce the formation of optical vortices or speckle compared to random initialization, as the analytic distribution is smooth in phase. IfNone, looks for"quadratic_phase"inflags. If afloatis provided, the size of the beam in the farfield is scaled accordingly. This feature is ignored ifphaseis notNone.
- save_stats(file_path, include_state=True)[source]#
Uses
save_h5()to export the statistics hierarchy to a given h5 file.- Parameters:
file_path (str) – Full path to the file to read the data from.
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().