Wavefront Module#

The cdiutils.wavefront module provides functions for X-ray wavefront analysis and propagation, particularly useful for characterising focusing optics and probe analysis in BCDI experiments.

Functions#

Wavefront Propagation#

cdiutils.wavefront.angular_spectrum_propagation(wavefront, propagation_distance, wavelength, pixel_size, magnification=1, do_fftshift=True, verbose=False)[source]#

Computes the near-field propagation of a wavefront using the Angular Spectrum Method.

Parameters:
  • wavefront (np.ndarray) – 2D or 3D complex array representing the wavefront. If the input is 2D, it will be converted to 3D with one slice. It can be fftshifted or not, see do_fftshift.

  • propagation_distance (float) – Propagation distance.

  • wavelength (float) – Wavelength of the wavefront.

  • pixel_size (float) – Pixel size in the spatial domain.

  • magnification (float, optional) – Magnification factor to handle the pixel size of the propagated wavefront (default is 1).

  • do_fftshift (bool, optional) – whether to apply fftshift to the wavefront before propagation. If True, the wavefront is fftshifted before propagation and ifftshifted after. Defaults to True.

  • verbose (bool) – whether to print z limits.

Returns:

Propagated wavefront at distance z.

Return type:

np.ndarray

cdiutils.wavefront.focus_probe(probe, pixel_size, wavelength, step_nb=200, step_size=1e-05, plot=True, **plot_kwargs)[source]#

Complete analysis of probe focus characteristics by propagating the probe through a range of distances and computing the focal distances. The function performs a probe focus sweep, computes the focal distances using the specified method (max), and plots the propagated probe with the focal distances. It returns the focused probe and the focal distances.

Parameters:
  • probe (np.ndarray) – the probe to be propagated, in the shape (height, width) or (modes, height, width). If 3D, the first dimension is considered as the propagation axis, and the rest are height and width. If 4D, will take the first mode only.

  • pixel_size (tuple) – the pixel size of the probe in meters, as a tuple (height, width) or a single float value for both dimensions.

  • wavelength (float) – the wavelength of the X-ray beam in meters.

  • step_nb (int, optional) – the number of steps for the propagation sweep. This defines the number of propagation positions. It determines how many times the probe is propagated through the range of distances. Defaults to 100.

  • step_size (float, optional) – the step size for the propagation sweep in meters. This defines the distance between each propagation position. Defaults to 10e-6.

  • plot (bool, optional) – whether to plot the propagated probe and focal distances. If True, the function will plot the propagated probe with the focal distances. If False, no plot is generated.Defaults to True.

Returns:

(focused_probe, focal_distances)

Return type:

tuple

cdiutils.wavefront.plot_propagated_probe(propagated_probe, pixel_size, propagation_step_size, convert_to_microns=True, focal_distances=None, plot_phase=True)[source]#

Plot the propagated probe as a 2D image with the phase or amplitude information. The function displays the probe at different propagation positions, with the option to plot the phase or amplitude. It also allows for the conversion of pixel size and propagation step size to microns. If focal distances are provided, vertical lines are drawn at those positions.

Parameters:
  • propagated_probe (np.ndarray) – the propagated probe data, in the shape (step_nb, height, width) or (modes, step_nb, height, width). If 3D, the first dimension is considered as the propagation axis, and the rest are height and width. If 4D, will take the first mode only.

  • pixel_size (tuple | float) – the pixel size of the probe in meters.

  • propagation_step_size (float, optional) – the step size for the propagation sweep in meters. This defines the distance between each propagation position. If convert_to_microns is True, this value is converted to microns.

  • convert_to_microns (bool, optional) – if True, converts the pixel size and propagation step size to microns. This is useful for displaying the probe in microns instead of meters. Defaults to True.

  • focal_distances (tuple | None, optional) – the focal distances where vertical lines are drawn on the plot. If provided, it should be a tuple of two values representing the focal distances in meters for both directions. If convert_to_microns is True, these values are converted to microns. If None, no vertical lines are drawn. Defaults to None.

  • plot_phase (bool, optional) – if True, plots the phase of the propagated probe. If False, plots the amplitude. The opacity of the phase plot is set to the sum of the absolute values along the propagation axis, normalised to the maximum value. Defaults to True.

Raises:
  • ValueError – if the propagated_probe is not 3D or 4D, or if the

  • pixel_size is not a float or a tuple of floats.

Returns:

the figure and axes objects for the propagated probe plot.

Return type:

tuple[plt.Figure, plt.Axes]

Probe Analysis#

cdiutils.wavefront.probe_metrics(probe, pixel_size, zoom_factor='auto', probe_convention='pynx', centre_at_max=False, verbose=False)[source]#

Plot the probe along with the line profile and its FWHM estimate. The probe is displayed in a 2D image, and the line profile is shown as a 1D plot. The FWHM is calculated and displayed on the line profile. If modes is True, all modes are plotted, otherwise only the first mode is plotted. > Notes: In the PyNX imshow plot of the probe, the origin is set to “lower” and exent is set to (-x_min, x_max, y_min, y_max). This means that in the PyNX convention, the probe is stored as a 2D (y = y_cxi, x = -x_cxi) array.

Parameters:
  • probe (np.ndarray) – the probe data to be plotted in matrix (y, x) convention.

  • pixel_size (tuple) – the pixel size of the probe data (y, x)

  • zoom_factor (int | str, optional) – the zoom factor for the probe plot. If “auto”, the window is set to be 3 times the FWHM. Defaults to “auto”.

  • probe_convention (str, optional) – the convention used for the probe data. If “pynx”, the probe is stored as a 2D (y = y_cxi, x = -x_cxi) array. Defaults to “pynx”.

  • centre_at_max (bool, optional) – if True, the probe is centred before the analysis. Defaults to False.

  • verbose (bool, optional) – if True, prints additional information. Defaults to False.

Returns:

the figure and axes objects for the probe and line profile plots.

Return type:

tuple

cdiutils.wavefront.get_width_metrics(profile, axis_values, verbose=False)[source]#

Compute the FWHM and other width metrics of a given profile. The function uses the find_peaks and peak_widths functions from scipy.signal to find the peaks and calculate the full width at half maximum (FWHM) and full width at 10% maximum (FW10%M) of the profile.

Parameters:
  • profile (np.ndarray) – the profile data to be analysed.

  • axis_values (np.ndarray) – the axis values corresponding to the profile data.

  • verbose (bool, optional) – whether to print out info. Defaults to False.

Returns:

a dictionary containing the FWHM and FW10%M values, their

indices, heights, and boundaries.

Return type:

dict

cdiutils.wavefront.probe_focus_sweep(probe, pixel_size, wavelength, step_nb=100, step_size=1e-05)[source]#

Propagate the probe through a range of distances using the angular spectrum method. The function computes the propagated probe at each distance and returns the propagated probe and the corresponding propagation positions.

Parameters:
  • probe (np.ndarray) – the probe to be propagated, in the shape (height, width) or (modes, height, width).

  • pixel_size (tuple) – the pixel size of the probe in meters.

  • wavelength (float) – the wavelength of the X-ray beam in meters.

  • step_nb (int, optional) – the number of steps for the propagation sweep. This defines the number of propagation positions. Defaults to 100.

  • step_size (_type_, optional) – the step size for the propagation sweep in meters. This defines the distance between each propagation position. Defaults to 10e-6 m.

Returns:

the propagated probe at each propagation position,

in the shape (step_nb, height, width) or (modes, step_nb, height, width).

np.ndarray: the propagation positions in meters.

Return type:

np.ndarray

cdiutils.wavefront.get_focal_distances(propagated_probe, propagation_positions, method='max')[source]#

Get the focal distances from the propagated probe data. The function computes the focal distances by reducing the probe data along the propagation axis using the specified method (sum or max). It returns the focal distances and the corresponding indexes in the propagation positions array.

Parameters:
  • propagated_probe (np.ndarray) – the propagated probe data, in the shape (step_nb, height, width) or (modes, step_nb, height, width). If 3D, the first dimension is considered as the propagation axis, and the rest are height and width. If 4D, will take the first mode only.

  • propagation_positions (np.ndarray) – the propagation positions in meters.

  • method (str, optional) – the method to use for reducing the probe data. Can be “sum” or “max”. If “sum”, the function computes the sum of the absolute values along the propagation axis and then finds the maximum. Defaults to “max”.

Raises:
  • ValueError – if the propagated_probe is not 3D or 4D.

  • ValueError – if the method is not “sum” or “max”.

Returns:

the focal distances as a tuple of two floats (focal_distance_1, focal_distance_2) and the corresponding indexes in the propagation positions array as a tuple of two integers (index_1, index_2).

Return type:

tuple[tuple[float, float], tuple[int, int]]

Examples#

Basic probe metrics analysis:

from cdiutils.wavefront import probe_metrics
import numpy as np

# Assuming 'probe' is a 2D complex array from reconstruction
pixel_size = (55e-9, 55e-9)  # metres

# Analyse probe characteristics
fig, metrics = probe_metrics(
    probe=probe,
    pixel_size=pixel_size,
    zoom_factor="auto",  # automatically determine zoom
    verbose=True
)

Wavefront propagation:

from cdiutils.wavefront import angular_spectrum_propagation

# Propagate probe to focal plane
propagation_distance = 0.1  # metres
wavelength = 1.5e-10  # metres
pixel_size = 55e-9  # metres

propagated = angular_spectrum_propagation(
    wavefront=probe,
    propagation_distance=propagation_distance,
    wavelength=wavelength,
    pixel_size=pixel_size,
    magnification=1.0
)

Find focal plane:

from cdiutils.wavefront import get_focal_distances, focus_probe

# Determine focal distances in x and y
focal_distances = get_focal_distances(
    probe=probe,
    wavelength=wavelength,
    pixel_size=pixel_size,
    propagation_range=(-0.5, 0.5),  # metres
    num_steps=100
)

# Focus probe to optimal plane
focused_probe = focus_probe(
    probe=probe,
    wavelength=wavelength,
    pixel_size=pixel_size,
    focal_distances=focal_distances
)

See Also#

cdiutils.process.PostProcessor : Uses probe for normalisation cdiutils.pipeline.BcdiPipeline : Access probe from reconstruction