Code reference
Refocus interface
Refocus is a user-convenient interface for numerical refocusing.
Each class implements refocusing for a specific dimensionality (1D or
2D fields) using a specific method for refocusing (e.g. numpy FFT or FFTW).
For 2D interfaces, inputs can be (y, x) or (..., y, x); when users
pass an n-dimensional input, the output array keeps that same
n-dimensional shape.
- nrefocus.get_best_interface()[source]
Return the fastest refocusing interface available
If cupy is installed,
nrefocus.RefocusCupyis returned. If cupy is not installed, then if pyfftw is installed,nrefocus.RefocusPyFFTWis returned. The fallback isnrefocus.RefocusNumpy.
- class nrefocus.RefocusPyFFTW(field, wavelength, pixel_size, medium_index=1.3333, distance=0, kernel='helmholtz', padding=True, input_domain='spatial', output_domain='spatial')[source]
Refocusing with FFTW
Added in version 0.4.0.
- Parameters:
field (complex-valued ndarray) – n-dimensional input field to be refocused. 1D
(x), 2D(y, x)and 3D(z, y, x)(e.g. 3D stack of 2D images) shapes are accepted. For data >3D, the final two dimensions are always assumed to be spatial. If ann-dimensional input is provided, the output keeps the same shape. The interpretation of field is controlled by input_domain.wavelength (float) – Wavelength of the used light [m]
pixel_size (float) – Pixel size of the input image [m]
medium_index (float) – Refractive index of the medium, defaults to water (1.3333 at 21.5°C)
distance (float) – Initial focusing distance [m]
kernel (str) –
Propagation kernel, one of
”helmholtz”: the optical transfer function \(\exp\left(id\left(\sqrt{k_\mathrm{m}^2 - k_\mathrm{x}^2 - k_\mathrm{y}^2} - k_\mathrm{m}\right)\right)\)
”fresnel”: paraxial approximation \(\exp(-id(k_\mathrm{x}^2+k_\mathrm{y}^2)/2k_\mathrm{m})\)
padding (bool) – Whether to perform boundary-padding with linear ramp
input_domain (str) –
Domain of field: either
"spatial"or"fourier". When"fourier", field must be in the fftshifted convention (DC at the centre of the array, as returned bynumpy.fft.fftshift()). Anifftshiftis applied internally so thatfft_originmatches the unshifted layout expected bynumpy.fft.fftfreq()-based kernels.Added in version 0.8.0.
output_domain (str) –
Domain of the propagated result: either
"spatial"or"fourier". When"fourier", the result is returned in the fftshifted convention (DC at the centre) via anfftshiftapplied after kernel multiplication so the caller receives data in the same convention as the input.Added in version 0.8.0.
- autofocus(interval, metric='average gradient', minimizer='lmfit', roi=None, minimizer_kwargs=None, ret_grid=False, ret_field=False)
Autofocus the initial field
- Parameters:
interval (tuple of floats) – Approximate interval to search for optimal focus [m]
metric (str) –
“average gradient” : average gradient metric of amplitude
”rms contrast” : RMS contrast of phase data
”spectrum” : sum of filtered Fourier coefficients
”std gradient” : standard deviation of gradient of amplitude
”med gradient” : median gradient metric of amplitude
minimizer (str) –
“legacy”: custom nrefocus minimizer
”lmfit”: lmfit-based minimizer (uses
lmfit.minimize)
roi (list or tuple or slice or ndarray) –
Region of interest for which the metric will be minimized. The axes below use the numpy indexing order. Options are: list or tuple or numpy indexing array (old behaviour):
[axis_0_start, axis_1_start, axis_0_end, axis_1_end] None can be used if no slicing is desired eg.: [None, None, axis_0_end, axis_1_end]
- list or tuple of slices (will be passed directly as is):
- (slice(axis_0_start, axis_0_end),
slice(axis_1_start, axis_1_end))
- None
The entire field will be used.
minimizer_kwargs (dict) – Any additional keyword arguments for the minimizer
ret_grid (bool) – return focus positions and metric values of the coarse grid search
ret_field (bool) – return the optimal refocused field for user convenience
- Returns:
af_distance (float) – Autofocusing distance
(d_grid, metrid_grid) (ndarray) – Coarse grid search values (only if ret_grid is True)
af_field (ndarray) – Autofocused field (only if ret_field is True)
[other] – Any other objects returned by minimizer; may be definable via minimizer_kwargs (depends on minimizer)
- backend_check()
Warn if the Refocus superclass doesn’t match expected backend. Raise an Error if the RefocusPyFFTW is used with numpy backend.
Added in version 0.6.0.
- get_kernel(distance)
Return the current kernel
Ther kernel type self.kernel is used (see
Refocus.__init__())
- propagate(distance)[source]
Propagate the initial field to a certain distance
- Parameters:
distance (float) – Absolute focusing distance [m]
- Returns:
refocused_field – Initial field refocused at distance, with the same shape as the input field.
- Return type:
ndarray
Notes
Any subclass should perform padding with
nrefocus.pad.pad_rem()during initialization.All subclasses follow the same Fourier shift convention when self.output_domain == “fourier”:
fft_originand the propagation kernel are both in unshifted layout (DC at index 0, matchingnumpy.fft.fftfreq()). Whenoutput_domain="fourier", subclasses must applyfftshiftbefore returning so the result is in the fftshifted convention (DC at centre), consistent withinput_domainand withqpretrieve.fourier.FourierFieldArtifact.finalize().
- property shape
Shape of the internal Fourier representation.
- class nrefocus.RefocusNumpy(field, wavelength, pixel_size, medium_index=1.3333, distance=0, kernel='helmholtz', padding=True, input_domain='spatial', output_domain='spatial')[source]
Refocusing with numpy-based Fourier transform
Added in version 0.3.0.
- Parameters:
field (complex-valued ndarray) – n-dimensional input field to be refocused. 1D
(x), 2D(y, x)and 3D(z, y, x)(e.g. 3D stack of 2D images) shapes are accepted. For data >3D, the final two dimensions are always assumed to be spatial. If ann-dimensional input is provided, the output keeps the same shape. The interpretation of field is controlled by input_domain.wavelength (float) – Wavelength of the used light [m]
pixel_size (float) – Pixel size of the input image [m]
medium_index (float) – Refractive index of the medium, defaults to water (1.3333 at 21.5°C)
distance (float) – Initial focusing distance [m]
kernel (str) –
Propagation kernel, one of
”helmholtz”: the optical transfer function \(\exp\left(id\left(\sqrt{k_\mathrm{m}^2 - k_\mathrm{x}^2 - k_\mathrm{y}^2} - k_\mathrm{m}\right)\right)\)
”fresnel”: paraxial approximation \(\exp(-id(k_\mathrm{x}^2+k_\mathrm{y}^2)/2k_\mathrm{m})\)
padding (bool) – Whether to perform boundary-padding with linear ramp
input_domain (str) –
Domain of field: either
"spatial"or"fourier". When"fourier", field must be in the fftshifted convention (DC at the centre of the array, as returned bynumpy.fft.fftshift()). Anifftshiftis applied internally so thatfft_originmatches the unshifted layout expected bynumpy.fft.fftfreq()-based kernels.Added in version 0.8.0.
output_domain (str) –
Domain of the propagated result: either
"spatial"or"fourier". When"fourier", the result is returned in the fftshifted convention (DC at the centre) via anfftshiftapplied after kernel multiplication so the caller receives data in the same convention as the input.Added in version 0.8.0.
- autofocus(interval, metric='average gradient', minimizer='lmfit', roi=None, minimizer_kwargs=None, ret_grid=False, ret_field=False)
Autofocus the initial field
- Parameters:
interval (tuple of floats) – Approximate interval to search for optimal focus [m]
metric (str) –
“average gradient” : average gradient metric of amplitude
”rms contrast” : RMS contrast of phase data
”spectrum” : sum of filtered Fourier coefficients
”std gradient” : standard deviation of gradient of amplitude
”med gradient” : median gradient metric of amplitude
minimizer (str) –
“legacy”: custom nrefocus minimizer
”lmfit”: lmfit-based minimizer (uses
lmfit.minimize)
roi (list or tuple or slice or ndarray) –
Region of interest for which the metric will be minimized. The axes below use the numpy indexing order. Options are: list or tuple or numpy indexing array (old behaviour):
[axis_0_start, axis_1_start, axis_0_end, axis_1_end] None can be used if no slicing is desired eg.: [None, None, axis_0_end, axis_1_end]
- list or tuple of slices (will be passed directly as is):
- (slice(axis_0_start, axis_0_end),
slice(axis_1_start, axis_1_end))
- None
The entire field will be used.
minimizer_kwargs (dict) – Any additional keyword arguments for the minimizer
ret_grid (bool) – return focus positions and metric values of the coarse grid search
ret_field (bool) – return the optimal refocused field for user convenience
- Returns:
af_distance (float) – Autofocusing distance
(d_grid, metrid_grid) (ndarray) – Coarse grid search values (only if ret_grid is True)
af_field (ndarray) – Autofocused field (only if ret_field is True)
[other] – Any other objects returned by minimizer; may be definable via minimizer_kwargs (depends on minimizer)
- backend_check()
Warn if the Refocus superclass doesn’t match expected backend. Raise an Error if the RefocusPyFFTW is used with numpy backend.
Added in version 0.6.0.
- get_kernel(distance)
Return the current kernel
Ther kernel type self.kernel is used (see
Refocus.__init__())
- property shape
Shape of the internal Fourier representation.
- class nrefocus.RefocusNumpy1D(field, wavelength, pixel_size, medium_index=1.3333, distance=0, kernel='helmholtz', padding=True, input_domain='spatial', output_domain='spatial')[source]
Refocus a 1D field with numpy
Added in version 0.3.0.
- Parameters:
field (1d complex-valued ndarray) – Input 1D field to be refocused
wavelength (float) – Wavelength of the used light [m]
pixel_size (float) – Pixel size of the input image [m]
medium_index (float) – Refractive index of the medium, defaults to water (1.3333 at 21.5°C)
distance (float) – Initial focusing distance [m]
kernel (str) –
Propagation kernel, one of
”helmholtz”: the optical transfer function \(\exp\left(id\left(\sqrt{k_\mathrm{m}^2 - k_\mathrm{x}^2} - k_\mathrm{m}\right)\right)\)
”fresnel”: paraxial approximation \(\exp(-idk_\mathrm{x}^2/2k_\mathrm{m})\)
padding (bool) – Wheter to perform boundary-padding with linear ramp
input_domain (str) –
Domain of field: either
"spatial"or"fourier". See the Refocus base class for more information.Added in version 0.8.0.
output_domain (str) –
Domain of the propagated result: either
"spatial"or"fourier". See the Refocus base class for more information.Added in version 0.8.0.
- autofocus(interval, metric='average gradient', minimizer='lmfit', roi=None, minimizer_kwargs=None, ret_grid=False, ret_field=False)
Autofocus the initial field
- Parameters:
interval (tuple of floats) – Approximate interval to search for optimal focus [m]
metric (str) –
“average gradient” : average gradient metric of amplitude
”rms contrast” : RMS contrast of phase data
”spectrum” : sum of filtered Fourier coefficients
”std gradient” : standard deviation of gradient of amplitude
”med gradient” : median gradient metric of amplitude
minimizer (str) –
“legacy”: custom nrefocus minimizer
”lmfit”: lmfit-based minimizer (uses
lmfit.minimize)
roi (list or tuple or slice or ndarray) –
Region of interest for which the metric will be minimized. The axes below use the numpy indexing order. Options are: list or tuple or numpy indexing array (old behaviour):
[axis_0_start, axis_1_start, axis_0_end, axis_1_end] None can be used if no slicing is desired eg.: [None, None, axis_0_end, axis_1_end]
- list or tuple of slices (will be passed directly as is):
- (slice(axis_0_start, axis_0_end),
slice(axis_1_start, axis_1_end))
- None
The entire field will be used.
minimizer_kwargs (dict) – Any additional keyword arguments for the minimizer
ret_grid (bool) – return focus positions and metric values of the coarse grid search
ret_field (bool) – return the optimal refocused field for user convenience
- Returns:
af_distance (float) – Autofocusing distance
(d_grid, metrid_grid) (ndarray) – Coarse grid search values (only if ret_grid is True)
af_field (ndarray) – Autofocused field (only if ret_field is True)
[other] – Any other objects returned by minimizer; may be definable via minimizer_kwargs (depends on minimizer)
- backend_check()
Warn if the Refocus superclass doesn’t match expected backend. Raise an Error if the RefocusPyFFTW is used with numpy backend.
Added in version 0.6.0.
- propagate(distance)[source]
Propagate the initial field to a certain distance
- Parameters:
distance (float) – Absolute focusing distance [m]
- Returns:
refocused_field – Initial 1D field refocused at distance
- Return type:
1d ndarray
- property shape
Shape of the internal Fourier representation.
Metrics
- nrefocus.metrics.metric_average_gradient(rfi, distance, roi=None, **kwargs)[source]
Compute mean average gradient norm of the amplitude
Notes
The absolute value of the gradient is returned.
- nrefocus.metrics.metric_med_gradient(rfi, distance, roi=None, **kwargs)[source]
Compute median gradient norm of the amplitude
Notes
The absolute value of the gradient is returned.
- nrefocus.metrics.metric_rms_contrast(rfi, distance, roi=None, **kwargs)[source]
Compute RMS contrast of the phase
Notes
The negative angle of the field is used for contrast estimation.
- nrefocus.metrics.metric_spectrum(rfi, distance, roi=None, **kwargs)[source]
Compute spectral contrast
Performs bandpass filtering in Fourier space according to optical limit of detection system, approximated by twice the wavelength.
- nrefocus.metrics.metric_std_gradient(rfi, distance, roi=None, **kwargs)[source]
Compute standard deviation (std) gradient of the amplitude
Notes
The absolute value of the gradient is returned.
- nrefocus.metrics.METRICS = {'average gradient': <function metric_average_gradient>, 'med gradient': <function metric_med_gradient>, 'rms contrast': <function metric_rms_contrast>, 'spectrum': <function metric_spectrum>, 'std gradient': <function metric_std_gradient>}
Available metrics
Minimizers
- nrefocus.minimizers.minimize_legacy(rf, metric_func, interval, roi=None, coarse_acc=1, fine_acc=0.005, ret_grid=False, ret_field=False)[source]
Legacy minimizer
Find the focus by minimizing the metric of an image. This is the implementation of the legacy nrefocus minimizer.
- Parameters:
rf (nrefocus.iface.Refocus) – Refocus interface
metric_func (callable) – metric called during minimization. The metric should take the following arguments: rf, distance, and roi
interval (tuple of floats) – (minimum, maximum) of interval to search [m]
roi (tuple of slices or xp.ndarray) – Region of interest for which the metric will be minimized. If not given, the entire field will be used.
coarse_acc (float) – accuracy for determination of global minimum in pixels; coarse_acc=1 means that 100 fields are computed in the initial step; coarse_acc=0.5 means 200 fields are computed
fine_acc (float) – accuracy for fine localization percentage of gradient change
ret_grid (bool) – return focus positions and metric values of the coarse grid search
ret_field (bool) – return the optimal refocused field for user convenience
- Returns:
af_dist (float) – Autofocusing distance [m]
(d_grid, metrid_grid) (ndarray) – Coarse grid search values (only if ret_grid is True)
af_field (ndarray) – Autofocused field (only if ret_field is True)
- nrefocus.minimizers.minimize_lmfit(rf, metric_func, interval, roi=None, lmfitkw=None, ret_grid=False, ret_field=False)[source]
A minimizer that wraps lmfit
Find the focus by minimizing the metric of an image A coarse grid search over interval with step size of 2*rf.wavelength is performed, followed by a “regular” minimization for the best candidate.
- Parameters:
rf (nrefocus.iface.Refocus) – Refocus interface
metric_func (callable) – metric called during minimization. The metric should take the following arguments: rf, distance, and roi
interval (tuple of floats) – (minimum, maximum) of interval to search [m]
roi (tuple of slices or xp.ndarray) – Region of interest for which the metric will be minimized. If not given, the entire field will be used.
lmfitkw – Additional keyword arguments for
lmfit.minimizeused in the fine grid search. The default method is “leastsq”.ret_grid (bool) – return focus positions and metric values of the coarse grid search
ret_field (bool) – return the optimal refocused field for user convenience
- Returns:
af_dist (float) – Autofocusing distance [m]
(d_grid, metrid_grid) (ndarray) – Coarse grid search values (only if ret_grid is True)
af_field (ndarray) – Autofocused field (only if ret_field is True)
- nrefocus.minimizers.MINIMIZERS = {'legacy': <function minimize_legacy>, 'lmfit': <function minimize_lmfit>}
Available minimizers
Legacy methods
These methods are legacy functions which are kept for backwards-compatibility.
Refocusing
- nrefocus.refocus(field, d, nm, res, method='helmholtz', padding=True, input_domain='spatial', output_domain='spatial')[source]
Refocus a 1D field or a 2D field / stack of 2D fields
- Parameters:
field (1d array or (..., y, x) array) – Background corrected electric field (Ex/BEx). For stacks, the last two axes are interpreted as spatial axes. The interpretation of field is controlled by input_domain. An object with fft_used and finalize() is also accepted; in that case the precomputed Fourier field is propagated directly.
d (float) – Distance to be propagated in pixels (negative for backwards)
nm (float) – Refractive index of medium
res (float) – Wavelength in pixels
method (str) –
Defines the method of propagation; one of
”helmholtz” : the optical transfer function exp(idkₘ(M-1))
”fresnel” : paraxial approximation exp(idk²/kₘ)
padding (bool) –
perform padding with linear ramp from edge to average to reduce ringing artifacts. Ignored for objects with fft_used and finalize(), which is the case of the qpretrieve artifact object.
Added in version 0.1.4.
input_domain (str) –
Either
"spatial"or"fourier". Default is"spatial"and treats field as in older nrefocus versions. If"fourier", field is treated as a precomputed Fourier-domain field and the initial FFT step is skipped.Added in version 0.8.0.
output_domain (str) –
Either
"spatial"or"fourier". Default is"spatial"and outputs inverse transformed field as in older nrefocus versions. If"fourier", the propagated Fourier-domain field is returned directly.Added in version 0.8.0.
- Return type:
Returns the propagated field in the requested output_domain.
Notes
This method uses
nrefocus.RefocusNumpyfor refocusing of 2D fields. This is because thenrefocus.refocus_stack()function uses async which appears to not work with e.g.pyfftw. Use rf = nrefocus.iface.RefocusCupy or RefocusPyFFTW syntax if you want to use CuPy or PyFFTW.
- nrefocus.refocus_stack(fieldstack, d, nm, res, method='helmholtz', num_cpus=2, copy=True, padding=True, input_domain='spatial', output_domain='spatial')[source]
Refocus a stack of 1D or 2D fields
- Parameters:
fieldstack (2d or 3d array) – Stack of 1D or 2D background corrected electric fields (Ex/BEx). The first axis iterates through the individual fields.
d (float) – Distance to be propagated in pixels (negative for backwards)
nm (float) – Refractive index of medium
res (float) – Wavelength in pixels
method (str) –
Defines the method of propagation; one of
”helmholtz” : the optical transfer function exp(idkₘ(M-1))
”fresnel” : paraxial approximation exp(idk²/kₘ)
num_cpus (int) – Defines the number of CPUs to be used for refocusing.
copy (bool) – If False, overwrites input stack.
padding (bool) –
Perform padding with linear ramp from edge to average to reduce ringing artifacts.
Added in version 0.1.4.
input_domain (str) –
Either
"spatial"or"fourier". Passed through torefocus().Added in version 0.8.0.
output_domain (str) –
Either
"spatial"or"fourier". Passed through torefocus().Added in version 0.8.0.
- Return type:
Returns the propagated stack in the requested output_domain.
Autofocusing
- nrefocus.autofocus(field, nm, res, ival, roi=None, metric='average gradient', minimizer='lmfit', minimizer_kwargs=None, padding=True, num_cpus=1)[source]
Numerical autofocusing of a field using the Helmholtz equation.
- Parameters:
field (1d or 2d ndarray) – Electric field is BG-Corrected, i.e. field = EX/BEx
nm (float) – Refractive index of medium.
res (float) – Size of wavelength in pixels.
ival (tuple of floats) – Approximate interval to search for optimal focus in px.
roi (rectangular region of interest (x1, y1, x2, y2)) – Region of interest of field for which the metric will be minimized. If not given, the entire field will be used.
metric (str) –
“average gradient” : average gradient metric of amplitude
”rms contrast” : RMS contrast of phase data
”spectrum” : sum of filtered Fourier coefficients
”std gradient” : standard deviation of gradient metric of amplitude
”med gradient” : median gradient metric of amplitude
minimizer (str) –
“lmfit” : lmfit-based minimizer
”legacy” : only use for reproducing old results
minimizer_kwargs (dict) – Optional keyword arguments to the minimizer function
padding (bool) –
Perform padding with linear ramp from edge to average to reduce ringing artifacts.
Changed in version 0.1.4: improved padding value and padding location
num_cpus (int) – Not implemented.
- Returns:
The focusing distance, the field, and optionally any other data returned by the minimizer (specify via minimizer_kwargs).
- Return type:
d, field [, other]
Notes
This method uses
nrefocus.RefocusNumpyfor refocusing of 2D fields. This is because thenrefocus.refocus_stack()function uses async which appears to not work with e.g.pyfftw.
- nrefocus.autofocus_stack(fieldstack, nm, res, ival, roi=None, metric='average gradient', minimizer='lmfit', minimizer_kwargs=None, padding=True, same_dist=False, num_cpus=2, copy=True)[source]
Numerical autofocusing of a stack using the Helmholtz equation.
- Parameters:
fieldstack (2d or 3d ndarray) – Electric field is BG-Corrected, i.e. Field = EX/BEx
nm (float) – Refractive index of medium.
res (float) – Size of wavelength in pixels.
ival (tuple of floats) – Approximate interval to search for optimal focus in px.
roi (rectangular region of interest (x1, y1, x2, y2)) – Region of interest of field for which the metric will be minimized. If not given, the entire field will be used.
metric (str) – see autofocus_field.
minimizer (str) –
“lmfit” : lmfit-based minimizer
”legacy” : only use for reproducing old results
minimizer_kwargs (dict) – Optional keyword arguments to the minimizer function
padding (bool) –
Perform padding with linear ramp from edge to average to reduce ringing artifacts.
Changed in version 0.1.4: improved padding value and padding location
same_dist (bool) – Refocus entire sinogram with one distance.
num_cpus (int) – Number of CPUs to use
copy (bool) – If False, overwrites input array.
- Returns:
dopt (float or list of float) – The focusing distance(s) (only one value if same_dist)
field_stack (xp.ndarray) – The refocused field stack