pyextal.larbed

Extraction of LARBED rocking curves from raw 4D-STEM data.

This is the stage that runs before refinement: it reads a raw EMPAD scan, indexes the reflections on a reciprocal-space grid, and integrates each one into a 2D rocking curve. The output feeds pyextal.dinfo.LARBEDDiffractionInfo directly via LARBEDAnalysis.to_dinfo(), or via an HDF5 file with LARBEDAnalysis.save_h5().

Merged in from the standalone PyLARBED package.

Example

>>> from pyextal.larbed import LARBEDAnalysis
>>> larbed = LARBEDAnalysis("scan_x256_y256.raw")
>>> larbed.load_data(type=0)
>>> larbed.average_data()
>>> larbed.assign_gvector((46, 48), (64, 36))
>>> larbed.calculate_grid_vectors(crop=2, order=3, Adjust=True)
>>> larbed.calculate_g_vectors((1, 3, -2), (4, 2, 0))
>>> larbed.IntegrateLarbed(ri=3, ro=(6, 8), g=580, m=0.47, Variance=True)
>>> dinfo = larbed.to_dinfo("si110.dat", thickness=1000, gl=37)

Submodules

Classes

LARBEDAnalysis

Turns a raw EMPAD scan into one rocking curve per reflection.

LARBEDCalibration

Measures the detector point-spread function and the tilt-scan step length.

Functions

ReadRaw(fname[, type])

Reads an EMPAD .raw file into a 4D array.

AlignByBeam(matrix, x, y[, crop, reiterate])

Aligns every pattern in the stack on the beam nearest a given position.

ApertureSum(matrix, center_x, center_y[, radius, bkg, ...])

Sums counts within a square aperture, optionally subtracting a background.

ApertureSumVariance(matrix, center_x, center_y[, g, ...])

Propagates counting variance through the same aperture as ApertureSum().

BackgroundFitWeights(center_x, center_y, radius, ri, ro)

Linear weights giving the fitted background summed under an aperture.

EstimatePixelNoise(matrix[, max_offset, counts, axis, ...])

Measures the per-pixel noise model and the inter-pixel noise correlation.

AnnularSum(matrix, center_x, center_y, ri, ro)

Averages counts within an annular aperture.

AnnularVar(matrix, center_x, center_y, g, m, DQE, ri, ro)

Computes the variance of the intensity inside an annular aperture.

Precession(matrix, center_x, center_y, ri, ro)

Averages diffraction patterns over an annulus of scan positions.

Precession_Angled(matrix, center_x, center_y, ri, ro, ...)

Averages diffraction patterns over an angular sector of an annulus.

FEM_StackAverage(matrix, center_x, center_y[, ...])

Computes a fluctuation electron microscopy variance image over the stack.

radial_profile(data, center)

Computes the azimuthally averaged radial profile of an image.

find_nearest_peak(vector, matrix[, crop])

Finds the brightest pixel within a window around a predicted position.

getGridVectors(x0, y0, x2, y2, x1, y1[, order, shape])

Builds a reciprocal-lattice grid from two basis vectors.

getGridVectors_Adjust(x0, y0, x1, y1, x2, y2, ...[, ...])

Builds a two-vector grid and snaps each node onto the nearest observed peak.

getGridVectorsHOLZ(x0, y0, x1, y1, x2, y2, x3, y3, x4, y4)

Builds a reciprocal-lattice grid from four basis vectors, including HOLZ.

get_gvectors(g1, g2, grid[, g3, g4])

Converts lattice indices on a pixel grid into Miller indices.

Package Contents

class pyextal.larbed.LARBEDAnalysis(file_name)

Turns a raw EMPAD scan into one rocking curve per reflection.

The usual sequence is load_data(), average_data() (or align_data()), assign_gvector(), calculate_grid_vectors(), calculate_g_vectors(), and IntegrateLarbed(). The result can then be handed to the refinement stage with to_dinfo() or save_h5(), or written as loose .npy files with save_larbed().

Variables:
  • file_name (str) – Path to the raw .raw file.

  • data (np.ndarray) – The 4D stack (scan_x, scan_y, det_x, det_y).

  • center (tuple[float, float]) – Direct-beam position on the detector.

  • IntRadius (int) – Aperture half-width used by align_data() and ZeroLarbed().

  • grid (list) – Reciprocal-lattice nodes as (index, pixel) pairs.

  • g_vectors (list) – Miller index of each grid node.

  • Store_Larbed (list) – Integrated intensity map per reflection.

  • Store_LarbedVariance (list) – Propagated variance per reflection.

  • Store_bkg (list) – Subtracted background per reflection.

  • Store_bkg_info (list) – With a fitted background, n_fit (fit pixels) and noise_gain per reflection.

  • noise (dict) – The detector noise model measured by estimate_noise().

file_name
data = []
average_raw = None
average_aligned = None
aligned = False
g_grid = None
g_vectors = None
Larbed = []
LarbedDeconvolved = []
gg_pixels = []
mtf_2d = None
mixing = None
center = (64, 64)
IntRadius = 4
IntZero = []
noise = None
property detector_shape

Detector shape (det_x, det_y) of the loaded stack.

Type:

tuple[int, int]

load_data(type=0)

Reads the raw file and centres the direct beam on the detector midpoint.

Parameters:

type (int, optional) – Detector layout, passed to pyextal.larbed.empad.ReadRaw(). Defaults to 0.

align_data(iterations=3)

Aligns the stack on the direct beam and stores before/after averages.

Parameters:

iterations (int, optional) – Number of alignment passes. Defaults to 3.

deconv_DPstack(mtf_2d, background=0, niter=100, varB=6.29, delta=0, A=1, g=580, m=None)

Deconvolves every diffraction pattern in the stack against the MTF.

Parameters:
  • mtf_2d (np.ndarray) – The modulation transfer function.

  • background (float, optional) – Pattern background. Defaults to 0.

  • niter (int, optional) – Lucy-Richardson iterations. Defaults to 100.

  • varB (float, optional) – Background variance. Defaults to 6.29.

  • delta (float, optional) – Squared percentage gain error. Defaults to 0.

  • A (float, optional) – Fano/conversion-gain parameter. Defaults to 1.

  • g (float, optional) – Detector gain. Defaults to 580.

  • m (float, optional) – Mixing factor. Derived from mtf_2d when None. Defaults to None.

deconv_Larbedstack(background=0, niter=100, varB=6.29, delta=0.0, A=1, g=1, mtf_2d=None, pad_size=None, m=1)

Deconvolves the integrated rocking curves against the MTF.

Note

Legacy. Because the rocking curves are already integrated over an aperture, deconvolution mainly adds noise; this step is normally skipped. It also discards the propagated variance.

Parameters:
  • background (float, optional) – Background level. Defaults to 0.

  • niter (int, optional) – Lucy-Richardson iterations. Defaults to 100.

  • varB (float, optional) – Background variance. Defaults to 6.29.

  • delta (float, optional) – Squared percentage gain error. Defaults to 0.0.

  • A (float, optional) – Fano/conversion-gain parameter. Defaults to 1.

  • g (float, optional) – Detector gain. Defaults to 1.

  • mtf_2d (np.ndarray, optional) – MTF to use. Falls back to self.mtf_2d. Defaults to None.

  • pad_size (int, optional) – Edge padding applied before deconvolution. Defaults to None (no padding).

  • m (float, optional) – Mixing factor. Defaults to 1.

average_data()

Averages the stack without aligning it.

assign_gvector(g1, g2, g3=None, g4=None)

Records the detector pixel positions of the basis reflections.

Supply two basis vectors for a zone-axis grid, or four to include HOLZ reflections.

Parameters:
  • g1 (tuple[float, float]) – Pixel position of the first basis reflection.

  • g2 (tuple[float, float]) – Pixel position of the second.

  • g3 (tuple[float, float], optional) – Pixel position of the third. Defaults to None.

  • g4 (tuple[float, float], optional) – Pixel position of the fourth. Defaults to None.

calculate_g_vectors(g1, g2, g3=None, g4=None)

Assigns a Miller index to every node of the pixel grid.

The number of basis vectors must match what was passed to assign_gvector().

Parameters:
  • g1 (tuple[int, int, int]) – Miller index of the first basis reflection.

  • g2 (tuple[int, int, int]) – Miller index of the second.

  • g3 (tuple[int, int, int], optional) – Miller index of the third. Defaults to None.

  • g4 (tuple[int, int, int], optional) – Miller index of the fourth. Defaults to None.

calculate_grid_vectors(crop=1, order=3, Adjust=True)

Builds the reciprocal-space grid of reflections on the detector.

Dispatches on how many basis vectors assign_gvector() was given: four selects the HOLZ grid, two selects either the peak-snapped or the plain lattice grid depending on Adjust.

Parameters:
  • crop (int, optional) – Half-width of the peak search window used when Adjust is True. Defaults to 1.

  • order (int | tuple[int, int, int, int], optional) – Grid extent. Must be a 4-tuple for the HOLZ grid, an int otherwise. Defaults to 3.

  • Adjust (bool, optional) – Snap each two-vector grid node onto the nearest observed peak. Defaults to True.

plot_averages(ratio=0.2)

Plots the stack average before and after alignment.

Parameters:

ratio (float, optional) – Fraction of the maximum used as the display ceiling. Defaults to 0.2.

ZeroLarbed(ratio=1)

Integrates and plots the rocking curve of the direct beam.

Parameters:

ratio (float, optional) – Fraction of the maximum used as the display ceiling. Defaults to 1.

plot_grid_vectors(ratio=0.2)

Overlays the reflection grid on the stack average.

Parameters:

ratio (float, optional) – Fraction of the maximum used as the display ceiling. Defaults to 0.2.

IntegrateLarbed(ri=4, ro=(0, 0), g=1, m=1, DQE=1, varB=0.0, Variance=False, bkg_fit=None, mask_neighbours=True, clip=True, rho=None)

Integrates each reflection into a rocking curve.

Reflections whose background-subtracted sum is nowhere positive are dropped from grid and g_vectors as well as from the output.

By default the background is the mean of the ro annulus. That mean is biased high next to a bright reflection, whose convex tail runs through the annulus, and the clipping at zero then wipes out much of a weak rocking curve. With bkg_fit set, a polynomial surface is fitted instead, for each reflection on each frame, to the annulus pixels that are outside the aperture and (with mask_neighbours) away from the other reflections; the fitted surface summed under the aperture is what gets subtracted. See pyextal.larbed.empad.BackgroundFitWeights().

Parameters:
  • ri (int, optional) – Aperture half-width in pixels. Defaults to 4.

  • ro (tuple[int, int], optional) – Inner and outer radii of the background annulus. (0, 0) disables background subtraction. Defaults to (0, 0).

  • g (float, optional) – Detector gain. Defaults to 1.

  • m (float, optional) – Mixing factor. Defaults to 1.

  • DQE (float, optional) – Detective quantum efficiency. Defaults to 1.

  • varB (float, optional) – Per-pixel background variance. Defaults to 0.0.

  • Variance (bool, optional) – Also propagate the counting variance. Defaults to False.

  • bkg_fit (int, optional) – Fit the background as a polynomial of order 0 (constant), 1 (plane) or 2 (quadratic) instead of using the annulus mean. Order 2 needs an annulus spanning a range of radii that stays clear of the neighbouring reflections, e.g. ri=3, ro=(4, 6). Defaults to None (annulus mean).

  • mask_neighbours (bool, optional) – With bkg_fit, leave pixels within ri of the other grid reflections out of the fit. Defaults to True.

  • clip (bool, optional) – Set negative intensities to zero. Passing False keeps the noise around zero unbiased; note that the jaxGeo oversub model and pyextal.acom.quality were written for clipped data. Defaults to True.

  • rho (np.ndarray, optional) – Inter-pixel noise correlation kernel from estimate_noise(). The variance then includes the covariance between neighbouring pixels, both inside the aperture and between the aperture and the background-fit pixels. Needs bkg_fit or no background. Defaults to None (independent pixels).

Raises:

ValueError – If bkg_fit is set without a background annulus, or rho with the annulus-mean background.

estimate_noise(**kwargs)

Measures the detector noise model from the scan itself.

See pyextal.larbed.empad.EstimatePixelNoise(). Pass the result to IntegrateLarbed() as m=noise['gm'] / g and rho=noise['rho'].

Parameters:

**kwargs – Passed to pyextal.larbed.empad.EstimatePixelNoise().

Returns:

gm, rho, gain_sum and n_pixels; also stored as self.noise.

Return type:

dict

plot_IntegratedLarbed(index, Variance=False)

Plots one integrated rocking curve, or all of them.

Parameters:
  • index (int | str) – Index of the reflection, or 'all'.

  • Variance (bool, optional) – Plot the variance map instead. Defaults to False.

deconvolve_image(index, niter=100, varB=6.29, delta=0, A=1, g=580)

Deconvolves a single integrated rocking curve against the MTF.

Parameters:
  • index (int) – Index of the reflection.

  • niter (int, optional) – Lucy-Richardson iterations. Defaults to 100.

  • varB (float, optional) – Background variance. Defaults to 6.29.

  • delta (float, optional) – Squared percentage gain error. Defaults to 0.

  • A (float, optional) – Fano/conversion-gain parameter. Defaults to 1.

  • g (float, optional) – Detector gain. Defaults to 580.

Returns:

The deconvolved rocking curve.

Return type:

np.ndarray

plot_larbed(rotation=-22, order_option=1, order=6, Circle_radius=8, a_expansion=1.6, ratio=0.2, Variance=False)

Plots every rocking curve at the position of its reflection.

Parameters:
  • rotation (float, optional) – Rotation applied to each rocking curve in degrees, aligning the tilt-scan axes with the pattern. Defaults to -22.

  • order_option (int, optional) – 0 filters reflections by the largest Miller index, 1 by the length of the g-vector. Defaults to 1.

  • order (int, optional) – Cutoff for the filter above. Defaults to 6.

  • Circle_radius (float, optional) – Radius of each rocking-curve disk. Defaults to 8.

  • a_expansion (float, optional) – Scaling applied to the disk positions. Defaults to 1.6.

  • ratio (float, optional) – Fraction of the display maximum used as the ceiling. Defaults to 0.2.

  • Variance (bool, optional) – Plot variance maps instead of intensities. Defaults to False.

stack()

Packs the integrated results into the arrays the refinement stage wants.

Returns:

The intensity stack shaped (n_beams, ny, nx), the matching variance stack (None if IntegrateLarbed() was run with Variance=False), and the Miller indices shaped (n_beams, 3).

Return type:

tuple[np.ndarray, np.ndarray | None, np.ndarray]

Raises:

RuntimeError – If IntegrateLarbed() has not been run.

to_dinfo(datpath, thickness, gl, tiltX=0.0, tiltY=0.0)

Builds a pyextal.dinfo.LARBEDDiffractionInfo from the results.

This is the direct handoff into the refinement stage, replacing a save_larbed() / np.load round-trip.

Parameters:
  • datpath (str | pathlib.Path) – Path to the crystal .dat file.

  • thickness (float) – Initial sample thickness estimate in Angstroms.

  • gl (float) – Tilt step size, as the number of steps spanning the x-axis reflection. See LARBED_Calibration.md.

  • tiltX (float, optional) – Initial tilt about x in degrees. Defaults to 0.0.

  • tiltY (float, optional) – Initial tilt about y in degrees. Defaults to 0.0.

Returns:

Ready to pass to pyextal.roi.LARBEDROI.

Return type:

pyextal.dinfo.LARBEDDiffractionInfo

save_h5(h5path, *, prefix='', crystal_dat='', date='')

Writes the integrated results into the /raw group of an HDF5 file.

This is the same file the pre-refinement and JAX refinement stages append to, so one dataset lives in one file end to end.

Parameters:
  • h5path (str | pathlib.Path) – Path to the HDF5 file, created if absent.

  • prefix (str, optional) – Acquisition prefix recorded as provenance. Defaults to “”.

  • crystal_dat (str, optional) – Name of the crystal .dat file recorded as provenance. Defaults to “”.

  • date (str, optional) – Acquisition date. Defaults to today.

save_larbed(filename)

Writes the integrated results as loose .npy files.

Parameters:

filename (str) – Path prefix. Four files are written, suffixed _Store_Larbed.npy, _Store_LarbedDeconvolved.npy, _Store_LarbedVariance.npy, and _g_vectors.npy.

out_larbed()

Returns the integrated results as Python lists.

Returns:

(Store_Larbed, Store_bkg, Store_LarbedVariance, g_vectors).

Return type:

tuple

class pyextal.larbed.LARBEDCalibration(file_name)

Measures the detector point-spread function and the tilt-scan step length.

The input is a reference scan taken with no sample and descan off, so only the direct beam is present and it walks across the detector. The usual sequence is load_data(), find_peaks(), calculate_average_step_length(), crop_peaks(), interpolate(), and calculate_mtf().

Variables:
  • data (np.ndarray) – The 4D reference stack.

  • peaks (np.ndarray) – Fitted (x, y) beam position at each scan step.

  • average_step_length (float) – Mean beam displacement per scan step, in detector pixels.

  • probe_image (np.ndarray) – The interpolated probe shape.

  • mtf_2d (np.ndarray) – The modulation transfer function, in the Fourier domain.

file_name
data = []
crop_data = []
probe_image = None
mtf_2d = None
peaks = None
roi_size = None
load_data(type=0)

Reads the reference scan and displays its middle pattern.

Parameters:

type (int, optional) – Detector layout, passed to pyextal.larbed.empad.ReadRaw(). Defaults to 0.

meanimage()

Averages the reference stack.

Returns:

The mean 2D pattern.

Return type:

np.ndarray

find_peaks(start=1, end=255)

Fits the beam position in every pattern of a square scan sub-region.

Parameters:
  • start (int, optional) – First scan index of the sub-region. Defaults to 1.

  • end (int, optional) – One past the last scan index. Defaults to 255.

crop_peaks(crop_size=20)

Crops and sub-pixel aligns a patch around each fitted beam position.

Parameters:

crop_size (int, optional) – Side length of each patch in pixels. Defaults to 20.

calculate_average_step_length()

Measures the mean beam displacement per scan step, in detector pixels.

This is the quantity that converts the tilt scan into reciprocal space; combined with the detector calibration and the length of the x-axis reflection it gives the gl passed to the refinement stage.

interpolate()

Rescales the averaged probe patch by the measured step length.

calculate_mtf(pad_size=256)

Transforms the probe image into a normalised Fourier-domain MTF.

The result is suitable for pyextal.LucyRichardson.lucy_Richardson() with mode='fourier'.

Parameters:

pad_size (int, optional) – Size the probe image is zero-padded to before the transform. Defaults to 256.

pyextal.larbed.ReadRaw(fname, type=0)

Reads an EMPAD .raw file into a 4D array.

Parameters:
  • fname (str | pathlib.Path) – Path to the .raw file.

  • type (int, optional) – Detector layout. 0 reads the standard 128x130 frame and crops the two trailing metadata rows to 124x124. 1 reads an already-cropped 124x124 frame. Defaults to 0.

Returns:

A (scan_x, scan_y, det_x, det_y) array with NaNs zeroed, negatives clipped to zero, and a 1e-10 floor applied so logarithms are safe.

Return type:

np.ndarray

pyextal.larbed.AlignByBeam(matrix, x, y, crop=4, reiterate=1)

Aligns every pattern in the stack on the beam nearest a given position.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • x (int) – Target position along the first detector axis.

  • y (int) – Target position along the second detector axis.

  • crop (int, optional) – Half-width of the search window around (x, y). Defaults to 4.

  • reiterate (int, optional) – Number of alignment passes. Defaults to 1.

Returns:

The aligned stack.

Return type:

np.ndarray

pyextal.larbed.ApertureSum(matrix, center_x, center_y, radius=0, bkg=(0, 0), fit=None, clip=True)

Sums counts within a square aperture, optionally subtracting a background.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • center_x (int) – Aperture centre along the first detector axis.

  • center_y (int) – Aperture centre along the second detector axis.

  • radius (int, optional) – Aperture half-width in pixels. 0 gives a single-pixel (point) virtual detector. Defaults to 0.

  • bkg (tuple[int, int], optional) – Inner and outer radii of an annulus whose mean intensity is subtracted. (0, 0) disables background subtraction. Ignored when fit is given. Defaults to (0, 0).

  • fit (tuple, optional) – (fi, fj, w, ...) from BackgroundFitWeights(); subtracts the fitted background instead of the annulus mean. Defaults to None.

  • clip (bool, optional) – Set negative results to zero. Defaults to True.

Returns:

The background-subtracted rocking curve and the subtracted background, both shaped (scan_x, scan_y).

Return type:

tuple[np.ndarray, np.ndarray]

pyextal.larbed.ApertureSumVariance(matrix, center_x, center_y, g=1, m=1, DQE=1, radius=0, bkg=(0, 0), varB=0.0, fit=None, rho=None)

Propagates counting variance through the same aperture as ApertureSum().

The per-pixel variance follows the detector noise model used elsewhere in pyextal (see pyextal.LucyRichardson.sgnoise()): a signal-dependent term g*m*I/DQE plus a constant readout term g*m*varB. Summing over count independent pixels scales the constant term by count.

Charge sharing makes neighbouring pixels’ noise correlated. Given the correlation kernel rho (see EstimatePixelNoise()), the variance is instead the full quadratic form u^T C u, with u = +1 on the aperture, -w on the fit pixels and C_kl = rho(k - l) * sigma_k * sigma_l. This includes the covariance between the aperture and the fit pixels next to it, which the independent-pixel sum leaves out.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • center_x (int) – Aperture centre along the first detector axis.

  • center_y (int) – Aperture centre along the second detector axis.

  • g (float, optional) – Detector gain. Defaults to 1.

  • m (float, optional) – Mixing factor. Defaults to 1.

  • DQE (float, optional) – Detective quantum efficiency. Defaults to 1.

  • radius (int, optional) – Aperture half-width in pixels. Defaults to 0.

  • bkg (tuple[int, int], optional) – Inner and outer radii of the background annulus, whose variance is propagated into the result. Ignored when fit is given. Defaults to (0, 0).

  • varB (float, optional) – Per-pixel background (readout) variance. Defaults to 0.0, which reproduces the original PyLARBED behaviour.

  • fit (tuple, optional) – (fi, fj, w, ...) from BackgroundFitWeights(). The same noise model is propagated through the fit weights, sum(w**2 * var_pixel); the fit pixels are disjoint from the aperture, so without rho the two terms add. Defaults to None.

  • rho (np.ndarray, optional) – Inter-pixel noise correlation, a (2R+1, 2R+1) kernel indexed by pixel offset with rho[R, R] = 1. Pairs further apart than R are taken as uncorrelated. Needs either fit or no background, because the annulus mean’s variance is estimated from its spatial spread rather than propagated. Defaults to None (independent pixels).

Returns:

The variance of the rocking curve, shaped (scan_x, scan_y).

Return type:

np.ndarray

Raises:

ValueError – If rho is combined with the annulus-mean background.

pyextal.larbed.BackgroundFitWeights(center_x, center_y, radius, ri, ro, order=2, shape=DEFAULT_DETECTOR_SHAPE, exclude=())

Linear weights giving the fitted background summed under an aperture.

A polynomial surface of the given order is fitted by unweighted least squares to the pixels of the annulus ri <= d <= ro that are neither in the aperture itself nor within radius (square half-width) of a node in exclude. Because the fit is linear, the fitted surface summed over the aperture pixels is data[fit pixels] @ w for a fixed w, so applying it to the stack fits every frame independently and exactly at once.

Note

On a symmetric annulus the plane terms cancel at the centre, so order=1 only differs from order=0 when masking or the detector edge makes the fit region asymmetric. order=2 corrects the curvature of a neighbour’s tail, but only if the annulus spans a range of radii: on a 1-px ring the isotropic curvature is nearly indistinguishable from the constant and the fit extrapolates noisily. The outer radius should still stay clear of the neighbouring cores, where a quadratic no longer describes the tail. For a Lorentzian tail from a reflection 10-20 px away, ri=3 with an annulus of (4, 6) cut the bias of the annulus mean by 10-30x, while (4, 8) overshot when the neighbour was only 10 px away.

Parameters:
  • center_x (int) – Aperture centre along the first detector axis.

  • center_y (int) – Aperture centre along the second detector axis.

  • radius (int) – Aperture half-width in pixels.

  • ri (int) – Inner radius of the fit annulus in pixels.

  • ro (int) – Outer radius of the fit annulus in pixels.

  • order (int, optional) – Polynomial order, 0 (constant), 1 (plane) or 2 (quadratic). Defaults to 2.

  • shape (tuple[int, int], optional) – Detector shape as (n_x, n_y). Defaults to DEFAULT_DETECTOR_SHAPE.

  • exclude (Iterable[tuple[float, float]], optional) – Pixel positions of other reflections whose surroundings are left out of the fit. Defaults to ().

Returns:

(fi, fj, w, gain) – the fit-pixel coordinates along each detector axis, their weights, and the noise gain ||w|| / (count / sqrt(n_fit)), which is 1 for a plain mean over the same pixels and grows as the fit extrapolates.

Return type:

tuple[np.ndarray, np.ndarray, np.ndarray, float]

Raises:

ValueError – If order is not 0, 1 or 2, or the fit region has too few pixels to determine the polynomial.

pyextal.larbed.EstimatePixelNoise(matrix, max_offset=3, counts=(5, 100), axis=1, stride=4, n_samples=400000, seed=0)

Measures the per-pixel noise model and the inter-pixel noise correlation.

Neighbouring scan positions see nearly the same pattern, so the second difference I[s-1] - 2 I[s] + I[s+1] along the scan removes the signal and leaves noise with six times the per-pixel variance. Its spread against intensity gives var = gm * I, and its correlation between nearby detector pixels gives rho.

Only pixels whose mean is between counts[0] and counts[1] effective counts (I / gm) are used. Below that, the zero-clipping in ReadRaw() truncates the noise; above it, real changes of the rocking curve between scan positions leak into the second difference.

Note

Difference along the fast scan axis (the default, axis=1), whose neighbours are adjacent in time. On EMPAD scans the slow axis carries line-to-line jumps that are not counting noise.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack (scan_x, scan_y, det_x, det_y).

  • max_offset (int, optional) – Largest pixel offset R of the correlation kernel. Defaults to 3.

  • counts (tuple[float, float], optional) – Range of effective counts per pixel used. Defaults to (5, 100).

  • axis (int, optional) – Scan axis to difference along. Defaults to 1.

  • stride (int, optional) – Use every stride-th scan line across the other axis, to bound the cost. Defaults to 4.

  • n_samples (int, optional) – Random samples per chunk for the variance-versus-intensity fit. Defaults to 400000.

  • seed (int, optional) – Seed for that subsampling. Defaults to 0.

Returns:

gm (per-pixel variance over intensity, i.e. g*m), rho (the (2R+1, 2R+1) correlation kernel, rho[R, R] = 1), gain_sum (gm * rho.sum(), the variance per unit intensity of a sum over a region much larger than the kernel), and n_pixels (the number of pixel samples behind rho).

Return type:

dict

Raises:

ValueError – If no intensity bin falls in the counts range.

pyextal.larbed.AnnularSum(matrix, center_x, center_y, ri, ro)

Averages counts within an annular aperture.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • center_x (int) – Annulus centre along the first detector axis.

  • center_y (int) – Annulus centre along the second detector axis.

  • ri (int) – Inner radius in pixels.

  • ro (int) – Outer radius in pixels.

Returns:

Mean intensity per scan position, shaped (scan_x, scan_y).

Return type:

np.ndarray

pyextal.larbed.AnnularVar(matrix, center_x, center_y, g, m, DQE, ri, ro)

Computes the variance of the intensity inside an annular aperture.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • center_x (int) – Annulus centre along the first detector axis.

  • center_y (int) – Annulus centre along the second detector axis.

  • g (float) – Detector gain. Unused; kept for signature compatibility.

  • m (float) – Mixing factor. Unused; kept for signature compatibility.

  • DQE (float) – Detective quantum efficiency. Unused; kept for signature compatibility.

  • ri (int) – Inner radius in pixels.

  • ro (int) – Outer radius in pixels.

Returns:

Variance across the annulus per scan position.

Return type:

np.ndarray

pyextal.larbed.Precession(matrix, center_x, center_y, ri, ro)

Averages diffraction patterns over an annulus of scan positions.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • center_x (int) – Annulus centre along the first scan axis.

  • center_y (int) – Annulus centre along the second scan axis.

  • ri (int) – Inner radius in scan steps.

  • ro (int) – Outer radius in scan steps.

Returns:

The averaged 2D diffraction pattern.

Return type:

np.ndarray

pyextal.larbed.Precession_Angled(matrix, center_x, center_y, ri, ro, angle1, angle2)

Averages diffraction patterns over an angular sector of an annulus.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • center_x (int) – Annulus centre along the first scan axis.

  • center_y (int) – Annulus centre along the second scan axis.

  • ri (int) – Inner radius in scan steps.

  • ro (int) – Outer radius in scan steps.

  • angle1 (float) – Start of the angular range in degrees.

  • angle2 (float) – End of the angular range in degrees.

Returns:

The averaged 2D diffraction pattern.

Return type:

np.ndarray

pyextal.larbed.FEM_StackAverage(matrix, center_x, center_y, Avg_img=None, rot_average=False)

Computes a fluctuation electron microscopy variance image over the stack.

Parameters:
  • matrix (np.ndarray) – 4D diffraction stack.

  • center_x (int) – Direct-beam position along the first detector axis.

  • center_y (int) – Direct-beam position along the second detector axis.

  • Avg_img (np.ndarray, optional) – Stack to average for the normalisation image. Defaults to None.

  • rot_average (bool, optional) – Add a rotationally averaged contribution. Defaults to False.

Returns:

The FEM image.

Return type:

np.ndarray

pyextal.larbed.radial_profile(data, center)

Computes the azimuthally averaged radial profile of an image.

Parameters:
  • data (np.ndarray) – 2D image.

  • center (tuple[int, int]) – Centre of the profile.

Returns:

Mean intensity as a function of integer radius.

Return type:

np.ndarray

pyextal.larbed.find_nearest_peak(vector, matrix, crop=4)

Finds the brightest pixel within a window around a predicted position.

Parameters:
  • vector (tuple[float, float]) – Predicted (x, y) position.

  • matrix (np.ndarray) – 2D image to search, typically the stack average.

  • crop (int, optional) – Half-width of the search window. Defaults to 4.

Returns:

Index of the brightest pixel.

Return type:

tuple[int, int]

pyextal.larbed.getGridVectors(x0, y0, x2, y2, x1, y1, order=3, shape=DEFAULT_DETECTOR_SHAPE)

Builds a reciprocal-lattice grid from two basis vectors.

Parameters:
  • x0 (float) – Direct-beam position along the first detector axis.

  • y0 (float) – Direct-beam position along the second detector axis.

  • x2 (float) – First basis-vector tip, first axis.

  • y2 (float) – First basis-vector tip, second axis.

  • x1 (float) – Second basis-vector tip, first axis.

  • y1 (float) – Second basis-vector tip, second axis.

  • order (int, optional) – Grid extent, giving indices -order..order along each basis vector. Defaults to 3.

  • shape (tuple[int, int], optional) – Detector shape used to reject off-detector nodes. Defaults to (124, 124).

Returns:

((i, j), (x, y)) pairs of lattice index and pixel position.

Return type:

list

pyextal.larbed.getGridVectors_Adjust(x0, y0, x1, y1, x2, y2, average_after, order=4, crop=2, shape=DEFAULT_DETECTOR_SHAPE)

Builds a two-vector grid and snaps each node onto the nearest observed peak.

Parameters:
  • x0 (float) – Direct-beam position along the first detector axis.

  • y0 (float) – Direct-beam position along the second detector axis.

  • x1 (float) – First basis-vector tip, first axis.

  • y1 (float) – First basis-vector tip, second axis.

  • x2 (float) – Second basis-vector tip, first axis.

  • y2 (float) – Second basis-vector tip, second axis.

  • average_after (np.ndarray) – Averaged 2D pattern used to locate peaks.

  • order (int, optional) – Grid extent along each basis vector. Defaults to 4.

  • crop (int, optional) – Half-width of the peak search window. Defaults to 2.

  • shape (tuple[int, int], optional) – Detector shape used to reject off-detector nodes. Defaults to (124, 124).

Returns:

((i, j), (x, y)) pairs, with (x, y) snapped to observed peaks.

Return type:

list

pyextal.larbed.getGridVectorsHOLZ(x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, order1=3, order2=3, order3=3, order4=3, shape=DEFAULT_DETECTOR_SHAPE)

Builds a reciprocal-lattice grid from four basis vectors, including HOLZ.

Parameters:
  • x0 (float) – Direct-beam position along the first detector axis.

  • y0 (float) – Direct-beam position along the second detector axis.

  • x1 (float) – Tips of the four basis vectors.

  • y1 (float) – Tips of the four basis vectors.

  • x2 (float) – Tips of the four basis vectors.

  • y2 (float) – Tips of the four basis vectors.

  • x3 (float) – Tips of the four basis vectors.

  • y3 (float) – Tips of the four basis vectors.

  • x4 (float) – Tips of the four basis vectors.

  • y4 (float) – Tips of the four basis vectors.

  • order1 (int, optional) – Extent along the first basis vector. Defaults to 3.

  • order2 (int, optional) – Extent along the second basis vector. Defaults to 3.

  • order3 (int, optional) – Extent along the third basis vector. Defaults to 3.

  • order4 (int, optional) – Extent along the fourth basis vector. Defaults to 3.

  • shape (tuple[int, int], optional) – Detector shape used to reject off-detector nodes. Defaults to (124, 124).

Returns:

((i, j, k, l), (x, y)) pairs of lattice index and pixel position.

Return type:

list

pyextal.larbed.get_gvectors(g1, g2, grid, g3=None, g4=None)

Converts lattice indices on a pixel grid into Miller indices.

Parameters:
  • g1 (tuple[int, int, int]) – Miller index of the first basis vector.

  • g2 (tuple[int, int, int]) – Miller index of the second basis vector.

  • grid (list) – Grid produced by getGridVectors(), getGridVectors_Adjust(), or getGridVectorsHOLZ().

  • g3 (tuple[int, int, int], optional) – Miller index of the third basis vector. Supply together with g4 for a four-vector (HOLZ) grid. Defaults to None.

  • g4 (tuple[int, int, int], optional) – Miller index of the fourth basis vector. Defaults to None.

Returns:

One Miller index per grid node.

Return type:

list[tuple[int, int, int]]